001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 * 019 */ 020package org.apache.mina.example.tapedeck; 021 022import java.nio.charset.Charset; 023import java.util.LinkedList; 024 025import org.apache.mina.core.buffer.IoBuffer; 026import org.apache.mina.core.filterchain.IoFilter.NextFilter; 027import org.apache.mina.core.session.IoSession; 028import org.apache.mina.filter.codec.ProtocolDecoder; 029import org.apache.mina.filter.codec.ProtocolDecoderOutput; 030import org.apache.mina.filter.codec.textline.LineDelimiter; 031import org.apache.mina.filter.codec.textline.TextLineDecoder; 032 033/** 034 * MINA {@link ProtocolDecoder} which decodes bytes into {@link Command} 035 * objects. 036 * 037 * @author <a href="http://mina.apache.org">Apache MINA Project</a> 038 */ 039public class CommandDecoder extends TextLineDecoder { 040 041 public CommandDecoder() { 042 super(Charset.forName("UTF8"), LineDelimiter.WINDOWS); 043 } 044 045 private Object parseCommand(String line) throws CommandSyntaxException { 046 String[] temp = line.split(" +", 2); 047 String cmd = temp[0].toLowerCase(); 048 String arg = temp.length > 1 ? temp[1] : null; 049 050 if (LoadCommand.NAME.equals(cmd)) { 051 if (arg == null) { 052 throw new CommandSyntaxException("No tape number specified"); 053 } 054 try { 055 return new LoadCommand(Integer.parseInt(arg)); 056 } catch (NumberFormatException nfe) { 057 throw new CommandSyntaxException("Illegal tape number: " + arg); 058 } 059 } else if (PlayCommand.NAME.equals(cmd)) { 060 return new PlayCommand(); 061 } else if (PauseCommand.NAME.equals(cmd)) { 062 return new PauseCommand(); 063 } else if (StopCommand.NAME.equals(cmd)) { 064 return new StopCommand(); 065 } else if (ListCommand.NAME.equals(cmd)) { 066 return new ListCommand(); 067 } else if (EjectCommand.NAME.equals(cmd)) { 068 return new EjectCommand(); 069 } else if (QuitCommand.NAME.equals(cmd)) { 070 return new QuitCommand(); 071 } else if (InfoCommand.NAME.equals(cmd)) { 072 return new InfoCommand(); 073 } else if (UserCommand.NAME.equals(cmd)) { 074 if (arg == null) { 075 throw new CommandSyntaxException("No username specified"); 076 } 077 return new UserCommand(arg); 078 } else if (PasswordCommand.NAME.equals(cmd)) { 079 if (arg == null) { 080 throw new CommandSyntaxException("No password specified"); 081 } 082 return new PasswordCommand(arg); 083 } 084 085 throw new CommandSyntaxException("Unknown command: " + cmd); 086 } 087 088 @Override 089 public void decode(IoSession session, IoBuffer in, final ProtocolDecoderOutput out) 090 throws Exception { 091 092 final LinkedList<String> lines = new LinkedList<String>(); 093 super.decode(session, in, new ProtocolDecoderOutput() { 094 public void write(Object message) { 095 lines.add((String) message); 096 } 097 public void flush(NextFilter nextFilter, IoSession session) {} 098 }); 099 100 for (String s: lines) { 101 out.write(parseCommand(s)); 102 } 103 } 104 105}