View Javadoc
1   /*
2    * This file is part of Waarp Project (named also Waarp or GG).
3    *
4    *  Copyright (c) 2019, Waarp SAS, and individual contributors by the @author
5    *  tags. See the COPYRIGHT.txt in the distribution for a full listing of
6    * individual contributors.
7    *
8    *  All Waarp Project is free software: you can redistribute it and/or
9    * modify it under the terms of the GNU General Public License as published by
10   * the Free Software Foundation, either version 3 of the License, or (at your
11   * option) any later version.
12   *
13   * Waarp is distributed in the hope that it will be useful, but WITHOUT ANY
14   * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
15   * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16   *
17   *  You should have received a copy of the GNU General Public License along with
18   * Waarp . If not, see <http://www.gnu.org/licenses/>.
19   */
20  package org.waarp.ftp.core.command;
21  
22  import org.waarp.common.command.CommandInterface;
23  import org.waarp.common.exception.InvalidArgumentException;
24  import org.waarp.common.file.SessionInterface;
25  import org.waarp.common.utility.WaarpStringUtils;
26  import org.waarp.ftp.core.config.FtpConfiguration;
27  import org.waarp.ftp.core.session.FtpSession;
28  
29  import java.util.regex.Pattern;
30  
31  /**
32   * Abstract definition of an FTP Command
33   */
34  public abstract class AbstractCommand implements CommandInterface {
35    private static final Pattern COMPILE_BLANK = WaarpStringUtils.BLANK;
36    /**
37     * Code of Command
38     */
39    private FtpCommandCode code;
40  
41    /**
42     * String attached to the command
43     */
44    private String command;
45  
46    /**
47     * Argument attached to this command
48     */
49    private String arg;
50  
51    /**
52     * The Ftp SessionInterface
53     */
54    private FtpSession session;
55  
56    /**
57     * Internal Object (whatever the used). This has to be clean by Business
58     * Handler cleanSession.
59     */
60    private Object object;
61  
62    /**
63     * Extra allowed nextCommand
64     */
65    private FtpCommandCode extraNextCommand;
66  
67    @Override
68    public final void setArgs(final SessionInterface session,
69                              final String command, final String arg,
70                              @SuppressWarnings("rawtypes") final Enum code) {
71      this.session = (FtpSession) session;
72      this.command = command;
73      this.arg = arg;
74      this.code = (FtpCommandCode) code;
75    }
76  
77    @Override
78    public final void setExtraNextCommand(
79        @SuppressWarnings("rawtypes") final Enum extraNextCommand) {
80      if (extraNextCommand != FtpCommandCode.NOOP) {
81        this.extraNextCommand = (FtpCommandCode) extraNextCommand;
82      } else {
83        this.extraNextCommand = null;
84      }
85    }
86  
87    @Override
88    public final boolean isNextCommandValid(
89        final CommandInterface newCommandArg) {
90      final AbstractCommand newCommand = (AbstractCommand) newCommandArg;
91      final Class<? extends AbstractCommand> newClass = newCommand.getClass();
92      // Special commands: QUIT ABORT STAT NOP
93      if (FtpCommandCode.isSpecialCommand(newCommand.getCode())) {
94        return true;
95      }
96      if (code == null) {
97        return false;
98      }
99      if (extraNextCommand != null) {
100       if (extraNextCommand.command == newClass) {
101         return true;
102       }
103       if (code.nextValids != null && code.nextValids.length > 0) {
104         for (final Class<?> nextValid : code.nextValids) {
105           if (nextValid == newClass) {
106             return true;
107           }
108         }
109       }
110       return false;
111     }
112     if (code.nextValids == null || code.nextValids.length == 0) {
113       // Any command is allowed
114       return true;
115     }
116     for (final Class<?> nextValid : code.nextValids) {
117       if (nextValid == newClass) {
118         return true;
119       }
120     }
121     return false;
122   }
123 
124   @Override
125   public final Object getObject() {
126     return object;
127   }
128 
129   @Override
130   public final void setObject(final Object object) {
131     this.object = object;
132   }
133 
134   @Override
135   public final String getArg() {
136     return arg;
137   }
138 
139   @Override
140   public final String[] getArgs() {
141     return COMPILE_BLANK.split(arg);
142   }
143 
144   @Override
145   public final int getValue(final String argx) throws InvalidArgumentException {
146     final int i;
147     try {
148       i = Integer.parseInt(argx);
149     } catch (final NumberFormatException e) {
150       throw new InvalidArgumentException("Not an integer", e);
151     }
152     return i;
153   }
154 
155   @Override
156   public final String getCommand() {
157     return command;
158   }
159 
160   @Override
161   public final boolean hasArg() {
162     return arg != null && arg.length() != 0;
163   }
164 
165   /**
166    * @return the current FtpSession
167    */
168   @Override
169   public final FtpSession getSession() {
170     return session;
171   }
172 
173   // some helpful functions
174 
175   /**
176    * @return The current configuration object
177    */
178   public final FtpConfiguration getConfiguration() {
179     return session.getConfiguration();
180   }
181 
182   @Override
183   public final void invalidCurrentCommand() {
184     session.getRestart().setSet(false);
185     session.setPreviousAsCurrentCommand();
186   }
187 
188   /**
189    * @return The FtpCommandCode associated with this command
190    */
191   @Override
192   public final FtpCommandCode getCode() {
193     return code;
194   }
195 }