001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.cli2.option; 018 019import java.util.Iterator; 020import java.util.ListIterator; 021import java.util.Set; 022 023import org.apache.commons.cli2.DisplaySetting; 024import org.apache.commons.cli2.Option; 025import org.apache.commons.cli2.WriteableCommandLine; 026import org.apache.commons.cli2.resource.ResourceConstants; 027import org.apache.commons.cli2.resource.ResourceHelper; 028 029/** 030 * A base implementation of Option providing limited ground work for further 031 * Option implementations. 032 */ 033public abstract class OptionImpl implements Option { 034 private final int id; 035 private final boolean required; 036 private Option parent; 037 038 /** 039 * Creates an OptionImpl with the specified id 040 * @param id the unique id of this Option 041 * @param required true iff this Option must be present 042 */ 043 public OptionImpl(final int id, 044 final boolean required) { 045 this.id = id; 046 this.required = required; 047 } 048 049 public boolean canProcess(final WriteableCommandLine commandLine, 050 final ListIterator arguments) { 051 if (arguments.hasNext()) { 052 final String argument = (String) arguments.next(); 053 arguments.previous(); 054 055 return canProcess(commandLine, argument); 056 } else { 057 return false; 058 } 059 } 060 061 public String toString() { 062 final StringBuffer buffer = new StringBuffer(); 063 appendUsage(buffer, DisplaySetting.ALL, null); 064 065 return buffer.toString(); 066 } 067 068 public int getId() { 069 return id; 070 } 071 072 public boolean equals(final Object thatObj) { 073 if (thatObj instanceof OptionImpl) { 074 final OptionImpl that = (OptionImpl) thatObj; 075 076 return (getId() == that.getId()) && 077 equals(getPreferredName(), that.getPreferredName()) && 078 equals(getDescription(), that.getDescription()) && 079 equals(getPrefixes(), that.getPrefixes()) && 080 equals(getTriggers(), that.getTriggers()); 081 } else { 082 return false; 083 } 084 } 085 086 private boolean equals(Object left, 087 Object right) { 088 if ((left == null) && (right == null)) { 089 return true; 090 } else if ((left == null) || (right == null)) { 091 return false; 092 } else { 093 return left.equals(right); 094 } 095 } 096 097 public int hashCode() { 098 int hashCode = getId(); 099 if (getPreferredName() != null) { 100 hashCode = (hashCode * 37) + getPreferredName().hashCode(); 101 } 102 103 if (getDescription() != null) { 104 hashCode = (hashCode * 37) + getDescription().hashCode(); 105 } 106 107 hashCode = (hashCode * 37) + getPrefixes().hashCode(); 108 hashCode = (hashCode * 37) + getTriggers().hashCode(); 109 110 return hashCode; 111 } 112 113 public Option findOption(String trigger) { 114 if (getTriggers().contains(trigger)) { 115 return this; 116 } else { 117 return null; 118 } 119 } 120 121 public boolean isRequired() { 122 return required; 123 } 124 125 public void defaults(final WriteableCommandLine commandLine) { 126 // nothing to do normally 127 } 128 129 public Option getParent() { 130 return parent; 131 } 132 133 public void setParent(Option parent) { 134 this.parent = parent; 135 } 136 137 protected void checkPrefixes(final Set prefixes) { 138 // nothing to do if empty prefix list 139 if (prefixes.isEmpty()) { 140 return; 141 } 142 143 // check preferred name 144 checkPrefix(prefixes, getPreferredName()); 145 146 // check triggers 147 this.getTriggers(); 148 149 for (final Iterator i = getTriggers().iterator(); i.hasNext();) { 150 checkPrefix(prefixes, (String) i.next()); 151 } 152 } 153 154 private void checkPrefix(final Set prefixes, 155 final String trigger) { 156 for (final Iterator i = prefixes.iterator(); i.hasNext();) { 157 String prefix = (String) i.next(); 158 159 if (trigger.startsWith(prefix)) { 160 return; 161 } 162 } 163 164 final ResourceHelper helper = ResourceHelper.getResourceHelper(); 165 final String message = 166 helper.getMessage(ResourceConstants.OPTION_TRIGGER_NEEDS_PREFIX, trigger, 167 prefixes.toString()); 168 throw new IllegalArgumentException(message); 169 } 170}