Java tutorial
/******************************************************************************* * Copyright (C) 2011 Atlas of Living Australia * All Rights Reserved. * * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. ******************************************************************************/ package au.org.ala.delta.intkey.directives; import java.util.ArrayDeque; import java.util.List; import java.util.Queue; import org.apache.commons.beanutils.BeanUtils; import org.apache.commons.lang.StringUtils; import au.org.ala.delta.directives.args.DirectiveArguments; import au.org.ala.delta.intkey.directives.invocation.IntkeyDirectiveInvocation; import au.org.ala.delta.intkey.model.IntkeyContext; /** * Base class for the majority of Intkey directives whose arguments follow a * standard pattern and can be handled by subclasses of IntkeyDirectiveArgument. * Directives that do not follow this pattern need to subclass IntkeyDirective * directly. * * @author ChrisF * */ public abstract class StandardIntkeyDirective extends IntkeyDirective { protected DirectiveArguments _args; protected List<IntkeyDirectiveFlag> _intkeyFlagsList; public StandardIntkeyDirective(boolean errorIfNoDatasetLoaded, String... controlWords) { super(errorIfNoDatasetLoaded, controlWords); _intkeyFlagsList = buildFlagsList(); } @Override public IntkeyDirectiveInvocation doProcess(IntkeyContext context, String data) throws Exception { StringBuilder stringRepresentationBuilder = new StringBuilder(); stringRepresentationBuilder.append(StringUtils.join(getControlWords(), " ").toUpperCase()); List<String> tokens = ParsingUtils.tokenizeDirectiveCall(data); Queue<String> tokenQueue = new ArrayDeque<String>(tokens); IntkeyDirectiveInvocation invoc = buildCommandObject(); if (_intkeyFlagsList != null && tokenQueue.size() > 0) { boolean matchingFlags = true; while (matchingFlags) { boolean tokenMatched = false; String token = tokenQueue.peek(); if (token != null) { for (IntkeyDirectiveFlag flag : _intkeyFlagsList) { if (flag.takesStringValue()) { // Flag can have a string value supplied with it in // format "/X=string", where X is the character // symbol. Note that // it is acceptable to supply such a flag without a // following equals sign and string value. if (token.matches("^/[" + Character.toLowerCase(flag.getSymbol()) + Character.toUpperCase(flag.getSymbol()) + "](=.+)?")) { // If string value is not supplied, it defaults // to empty string String flagStringValue = ""; String[] tokenPieces = token.split("="); // There should only be 0 or 1 equals sign. If // more than none is supplied, no match. if (tokenPieces.length < 3) { if (tokenPieces.length == 2) { flagStringValue = tokenPieces[1]; } BeanUtils.setProperty(invoc, flag.getName(), flagStringValue); tokenQueue.remove(); tokenMatched = true; stringRepresentationBuilder.append(" "); stringRepresentationBuilder.append(token); break; } } } else { if (token.equalsIgnoreCase("/" + flag.getSymbol())) { BeanUtils.setProperty(invoc, flag.getName(), true); tokenQueue.remove(); tokenMatched = true; stringRepresentationBuilder.append(" "); stringRepresentationBuilder.append(token); break; } } } matchingFlags = tokenMatched; } else { matchingFlags = false; } } } // The arguments list needs to be generated each time a call to the // directive is processed. This is // because most arguments need to have provided with an initial value // which is used when prompting the user. // This initial value needs to be read out of the IntkeyContext at the // time of parsing. // E.g. the integer argument for the SET TOLERANCE directive will have // an initial value equal to the // the value of the tolerance setting before the call to the directive. List<IntkeyDirectiveArgument<?>> intkeyArgsList = generateArgumentsList(context); if (intkeyArgsList != null) { for (IntkeyDirectiveArgument<?> arg : intkeyArgsList) { Object parsedArgumentValue = arg.parseInput(tokenQueue, context, StringUtils.join(_controlWords, " "), stringRepresentationBuilder); if (parsedArgumentValue != null) { BeanUtils.setProperty(invoc, arg.getName(), parsedArgumentValue); } else { // No argument value supplied, user cancelled out of the // prompt dialog. return null; } } } invoc.setStringRepresentation(stringRepresentationBuilder.toString()); return invoc; } protected abstract List<IntkeyDirectiveArgument<?>> generateArgumentsList(IntkeyContext context); protected abstract List<IntkeyDirectiveFlag> buildFlagsList(); protected abstract IntkeyDirectiveInvocation buildCommandObject(); }