1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 *
19 */
20 package org.apache.mina.filter.codec.textline;
21
22 import java.nio.charset.Charset;
23 import java.nio.charset.CharsetEncoder;
24
25 import org.apache.mina.core.buffer.IoBuffer;
26 import org.apache.mina.core.session.AttributeKey;
27 import org.apache.mina.core.session.IoSession;
28 import org.apache.mina.filter.codec.ProtocolEncoder;
29 import org.apache.mina.filter.codec.ProtocolEncoderAdapter;
30 import org.apache.mina.filter.codec.ProtocolEncoderOutput;
31
32 /**
33 * A {@link ProtocolEncoder} which encodes a string into a text line
34 * which ends with the delimiter.
35 *
36 * @author <a href="http://mina.apache.org">Apache MINA Project</a>
37 */
38 public class TextLineEncoder extends ProtocolEncoderAdapter {
39 private final AttributeKey ENCODER = new AttributeKey(getClass(), "encoder");
40
41 private final Charset charset;
42
43 private final LineDelimiter delimiter;
44
45 private int maxLineLength = Integer.MAX_VALUE;
46
47 /**
48 * Creates a new instance with the current default {@link Charset}
49 * and {@link LineDelimiter#UNIX} delimiter.
50 */
51 public TextLineEncoder() {
52 this(Charset.defaultCharset(), LineDelimiter.UNIX);
53 }
54
55 /**
56 * Creates a new instance with the current default {@link Charset}
57 * and the specified <tt>delimiter</tt>.
58 */
59 public TextLineEncoder(String delimiter) {
60 this(new LineDelimiter(delimiter));
61 }
62
63 /**
64 * Creates a new instance with the current default {@link Charset}
65 * and the specified <tt>delimiter</tt>.
66 */
67 public TextLineEncoder(LineDelimiter delimiter) {
68 this(Charset.defaultCharset(), delimiter);
69 }
70
71 /**
72 * Creates a new instance with the spcified <tt>charset</tt>
73 * and {@link LineDelimiter#UNIX} delimiter.
74 */
75 public TextLineEncoder(Charset charset) {
76 this(charset, LineDelimiter.UNIX);
77 }
78
79 /**
80 * Creates a new instance with the spcified <tt>charset</tt>
81 * and the specified <tt>delimiter</tt>.
82 */
83 public TextLineEncoder(Charset charset, String delimiter) {
84 this(charset, new LineDelimiter(delimiter));
85 }
86
87 /**
88 * Creates a new instance with the spcified <tt>charset</tt>
89 * and the specified <tt>delimiter</tt>.
90 */
91 public TextLineEncoder(Charset charset, LineDelimiter delimiter) {
92 if (charset == null) {
93 throw new NullPointerException("charset");
94 }
95 if (delimiter == null) {
96 throw new NullPointerException("delimiter");
97 }
98 if (LineDelimiter.AUTO.equals(delimiter)) {
99 throw new IllegalArgumentException(
100 "AUTO delimiter is not allowed for encoder.");
101 }
102
103 this.charset = charset;
104 this.delimiter = delimiter;
105 }
106
107 /**
108 * Returns the allowed maximum size of the encoded line.
109 * If the size of the encoded line exceeds this value, the encoder
110 * will throw a {@link IllegalArgumentException}. The default value
111 * is {@link Integer#MAX_VALUE}.
112 */
113 public int getMaxLineLength() {
114 return maxLineLength;
115 }
116
117 /**
118 * Sets the allowed maximum size of the encoded line.
119 * If the size of the encoded line exceeds this value, the encoder
120 * will throw a {@link IllegalArgumentException}. The default value
121 * is {@link Integer#MAX_VALUE}.
122 */
123 public void setMaxLineLength(int maxLineLength) {
124 if (maxLineLength <= 0) {
125 throw new IllegalArgumentException("maxLineLength: "
126 + maxLineLength);
127 }
128
129 this.maxLineLength = maxLineLength;
130 }
131
132 public void encode(IoSession session, Object message,
133 ProtocolEncoderOutput out) throws Exception {
134 CharsetEncoder encoder = (CharsetEncoder) session.getAttribute(ENCODER);
135 if (encoder == null) {
136 encoder = charset.newEncoder();
137 session.setAttribute(ENCODER, encoder);
138 }
139
140 String value = message.toString();
141 IoBuffer buf = IoBuffer.allocate(value.length())
142 .setAutoExpand(true);
143 buf.putString(value, encoder);
144 if (buf.position() > maxLineLength) {
145 throw new IllegalArgumentException("Line length: " + buf.position());
146 }
147 buf.putString(delimiter.getValue(), encoder);
148 buf.flip();
149 out.write(buf);
150 }
151
152 public void dispose() throws Exception {
153 // Do nothing
154 }
155 }