2222
2323import com .google .common .base .Predicate ;
2424import com .google .protobuf .Descriptors .FileDescriptor ;
25+ import com .google .protobuf .Duration ;
2526import com .google .protobuf .Message ;
2627import com .google .protobuf .Timestamp ;
2728import org .spine3 .protobuf .EntityPackagesMap ;
3940import static com .google .common .base .Preconditions .checkArgument ;
4041import static com .google .common .base .Preconditions .checkNotNull ;
4142import static com .google .protobuf .util .TimeUtil .getCurrentTime ;
43+ import static org .spine3 .validate .Validate .isNotDefault ;
4244
4345/**
4446 * Client-side utilities for working with commands.
4850public class Commands {
4951
5052 /**
51- * A substring which the {@code .proto} file containing commands must have in its name.
53+ * A suffix which the {@code .proto} file containing commands must have in its name.
5254 */
53- public static final String COMMANDS_FILE_SUBSTRING = "commands" ;
55+ public static final String FILE_NAME_SUFFIX = "commands" ;
5456
55- private static final char PROTO_FILE_SEPARATOR = '/' ;
57+ private static final char FILE_PATH_SEPARATOR = '/' ;
58+ private static final char FILE_EXTENSION_SEPARATOR = '.' ;
5659
5760 private Commands () {}
5861
@@ -193,13 +196,14 @@ public static String formatMessageTypeAndId(String format, Message commandMessag
193196 * Checks if the file is for commands.
194197 *
195198 * @param file a descriptor of a {@code .proto} file to check
196- * @return {@code true} if the file name contains {@link #COMMANDS_FILE_SUBSTRING} substring , {@code false} otherwise
199+ * @return {@code true} if the file name ends with the {@link #FILE_NAME_SUFFIX} , {@code false} otherwise
197200 */
198201 public static boolean isCommandsFile (FileDescriptor file ) {
199202 final String fqn = file .getName ();
200- final int startIndexOfFileName = fqn .lastIndexOf (PROTO_FILE_SEPARATOR ) + 1 ;
201- final String fileName = fqn .substring (startIndexOfFileName );
202- final boolean isCommandsFile = fileName .contains (COMMANDS_FILE_SUBSTRING );
203+ final int startIndexOfFileName = fqn .lastIndexOf (FILE_PATH_SEPARATOR ) + 1 ;
204+ final int endIndexOfFileName = fqn .lastIndexOf (FILE_EXTENSION_SEPARATOR );
205+ final String fileName = fqn .substring (startIndexOfFileName , endIndexOfFileName );
206+ final boolean isCommandsFile = fileName .endsWith (FILE_NAME_SUFFIX );
203207 return isCommandsFile ;
204208 }
205209
@@ -216,4 +220,20 @@ public static boolean isEntityFile(FileDescriptor file) {
216220 final boolean isCommandForEntity = EntityPackagesMap .contains (protoPackage );
217221 return isCommandForEntity ;
218222 }
223+
224+ /**
225+ * Checks if the command is scheduled to be delivered later.
226+ *
227+ * @param command a command to check
228+ * @return {@code true} if the command context has a scheduling option set, {@code false} otherwise
229+ */
230+ public static boolean isScheduled (Command command ) {
231+ final Schedule schedule = command .getContext ().getSchedule ();
232+ final Duration delay = schedule .getAfter ();
233+ if (isNotDefault (delay )) {
234+ checkArgument (delay .getSeconds () > 0 , "Command delay seconds must be a positive value." );
235+ return true ;
236+ }
237+ return false ;
238+ }
219239}
0 commit comments