⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 formfield.java

📁 HTML解析器是一个Java库
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
	 * <a href="FormControl.html#UserValueControl">user value control</a> with the same name.
	 * This would nearly always indicate an unintentional error in the HTML source document,
	 * in which case your application can either log a warning that a poorly designed form has been encountered,
	 * or take special action to try to interpret the multiple user values that might be submitted.
	 *
	 * @return the number of constituent <a href="FormControl.html#UserValueControl">user value controls</a> in this field.
	 */
	public int getUserValueCount() {
		return userValueCount;
	}

	/**
	 * Returns a collection of the {@linkplain FormControl#getPredefinedValue() predefined values} of all constituent {@linkplain FormControl controls} in this field.
	 * <p>
	 * All objects in the returned collection are of type <code>String</code>, with no <code>null</code> entries.
	 * <p>
	 * An interator over this collection returns the values in the order of appearance in the source document.
	 *
	 * @return a collection of the {@linkplain FormControl#getPredefinedValue() predefined values} of all constituent {@linkplain FormControl controls} in this field, or <code>null</code> if none.
	 * @see FormControl#getPredefinedValues()
	 */
	public Collection<String> getPredefinedValues() {
		if (predefinedValues==null) return Collections.emptySet();
		return predefinedValues;
	}

	/**
	 * Returns a list of the <a href="#FieldSubmissionValues">field submission values</a> in order of appearance.
	 * <p>
	 * The term <i><a name="FieldSubmissionValues">field submission values</a></i> is used in this library to refer to the aggregate of all the
	 * <a href="FormControl.html#SubmissionValue">submission values</a> of a field's constituent {@linkplain #getFormControls() form controls}.
	 * <p>
	 * All objects in the returned list are of type <code>String</code>, with no <code>null</code> entries.
	 * <p>
	 * The list may contain duplicates if the this field has multiple controls with the same value.
	 *
	 * @return a list of the <a href="#FieldSubmissionValues">field submission values</a> in order of appearance, guaranteed not <code>null</code>.
	 */
	public List<String> getValues() {
		final List<String> values=new ArrayList<String>();
		for (FormControl formControl : formControls) formControl.addValuesTo(values);
		return values;
	}

	/**
	 * Clears the <a href="FormControl.html#SubmissionValue">submission values</a> of all the constituent {@linkplain #getFormControls() form controls} in this field.
	 * @see FormControl#clearValues()
	 */
	public void clearValues() {
		for (FormControl formControl : formControls) formControl.clearValues();
	}

	/**
	 * Sets the <a href="#FieldSubmissionValues">field submission values</a> of this field to the specified values.
	 * <p>
	 * This is equivalent to calling {@link #clearValues()} followed by {@link #addValue(String) addValue(value)} for each
	 * value in the specified collection.
	 * <p>
	 * The specified collection must not contain any <code>null</code> values.
	 *
	 * @param values  the new <a href="#FieldSubmissionValues">field submission values</a> of this field.
	 * @see #addValue(String value)
	 */
	public void setValues(final Collection<String> values) {
		clearValues();
		addValues(values);
	}

	/**
	 * Sets the <a href="#FieldSubmissionValues">field submission values</a> of this field to the single specified value.
	 * <p>
	 * This is equivalent to calling {@link #clearValues()} followed by {@link #addValue(String) addValue(value)}.
	 * <p>
	 * The return value indicates whether any of the constituent form controls "accepted" the value.
	 * A return value of <code>false</code> implies an error condition as the specified value is not compatible with this field.
	 * <p>
	 * Specifying a <code>null</code> value is equivalent to calling {@link #clearValues()} alone, and always returns <code>true</code>.
	 * <p>
	 * See the {@link #addValue(String value)} method for more information.
	 *
	 * @param value  the new <a href="#FieldSubmissionValues">field submission value</a> of this field, or <code>null</code> to {@linkplain #clearValues() clear} the field of all submission values.
	 * @return <code>true</code> if one of the constituent {@linkplain #getFormControls() form controls} accepts the value, otherwise <code>false</code>.
	 * @see FormFields#setValue(String fieldName, String value)
	 */
	public boolean setValue(final String value) {
		clearValues();
		return value!=null ? addValue(value) : true;
	}

	/**
	 * Adds the specified value to the <a href="#FieldSubmissionValues">field submission values</a> of this field.
	 * <p>
	 * This is achieved internally by attempting to {@linkplain FormControl#addValue(String) add the value} to every constituent 
	 * {@linkplain #getFormControls() form control} until one "accepts" it.
	 * <p>
	 * The return value indicates whether any of the constituent form controls accepted the value.
	 * A return value of <code>false</code> implies an error condition as the specified value is not compatible with this field.
	 * <p>
	 * In the unusual case that this field consists of multiple form controls, but not all of them are
	 * <a href="FormControl.html#PredefinedValueControl">predefined value controls</a>, priority is given to the predefined value controls
	 * before attempting to add the value to the <a href="FormControl.html#UserValueControl">user value controls</a>.
	 *
	 * @param value  the new <a href="#FieldSubmissionValues">field submission value</a> to add to this field, must not be <code>null</code>.
	 * @return <code>true</code> if one of the constituent {@linkplain #getFormControls() form controls} accepts the value, otherwise <code>false</code>.
	 */
	public boolean addValue(final String value) {
		if (value==null) throw new IllegalArgumentException("value argument must not be null");
		if (formControls.size()==1) return getFirstFormControl().addValue(value);
		List<FormControl> userValueControls=null;
		for (FormControl formControl : formControls) {
			if (!formControl.getFormControlType().hasPredefinedValue()) {
				// A user value control has been found, but is not the only control with this name.
				// This shouldn't normally happen in a well designed form, but we will save the user value control
				// for later and give all predefined value controls first opportunity to take the value.
				if (userValueControls==null) userValueControls=new LinkedList<FormControl>();
				userValueControls.add(formControl);
				continue;
			}
			if (formControl.addValue(value)) return true; // return value of true from formControl.addValue(value) means the value was taken by the control
		}
		if (userValueControls==null) return false;
		for (FormControl userFormControl : userValueControls) {
			if (userFormControl.addValue(value)) return true;
		}
		return false;
	}

	/**
	 * Returns a string representation of this object useful for debugging purposes.
	 * @return a string representation of this object useful for debugging purposes.
	 */
	public String getDebugInfo() {
		final StringBuilder sb=new StringBuilder();
		sb.append("Field: ").append(name).append(", UserValueCount=").append(userValueCount).append(", AllowsMultipleValues=").append(allowsMultipleValues);
		if (predefinedValues!=null) {
			for (String predefinedValue : predefinedValues) sb.append(Config.NewLine).append("PredefinedValue: ").append(predefinedValue);
		}
		for (FormControl formControl : formControls) sb.append(Config.NewLine).append("FormControl: ").append(formControl.getDebugInfo());
		sb.append(Config.NewLine).append(Config.NewLine);
		return sb.toString();
	}

	/**
	 * Returns a string representation of this object useful for debugging purposes.
	 * <p>
	 * This is equivalent to {@link #getDebugInfo()}.
	 *
	 * @return a string representation of this object useful for debugging purposes.
	 */
	public String toString() {
		return getDebugInfo();
	}

	void addValues(final Collection<String> values) {
		if (values!=null) for (String value : values) addValue(value);
	}

	void addValues(final String[] values) {
		if (values!=null) for (String value : values) addValue(value);
	}

	void addFormControl(final FormControl formControl, final String predefinedValue) {
		// predefinedValue==null if we are adding a user value
		if (predefinedValue==null) {
			userValueCount++;
		} else {
			if (predefinedValues==null) predefinedValues=new LinkedHashSet<String>();
			predefinedValues.add(predefinedValue);
		}
		formControls.add(formControl);
		allowsMultipleValues=calculateAllowsMultipleValues(formControl);
	}

	private boolean calculateAllowsMultipleValues(final FormControl newFormControl) {
		// false if only one control (unless it is a multiple select with more than one option),
		// or all of the controls are radio buttons, or all of the controls are submit buttons
		if (allowsMultipleValues || userValueCount>1) return true;
		if (userValueCount==1) return predefinedValues!=null;
		// at this stage we know userValueCount==0  && predefinedValues.size()>=1
		if (predefinedValues.size()==1) return false;
		final FormControlType newFormControlType=newFormControl.getFormControlType();
		if (formControls.size()==1) return newFormControlType==FormControlType.SELECT_MULTIPLE;
		// at this stage we know there are multiple predefined values in multiple controls.
		// if all of the controls are radio buttons or all are submit buttons, allowsMultipleValues is false, otherwise true.
		// checking only the first control and the new control is equivalent to checking them all because if they weren't all
		// the same allowsMultipleValues would already be true.
		final FormControlType firstFormControlType=getFirstFormControl().getFormControlType();
		if (newFormControlType==FormControlType.RADIO && firstFormControlType==FormControlType.RADIO) return false;
		if (newFormControlType.isSubmit() && firstFormControlType.isSubmit()) return false;
		return true;
	}

	FormControl getFirstFormControl() {
		// formControls must be ordered collection for this method to work.
		// It has to return the first FormControl entered into the collection
		// for the algorithm in calculateAllowsMultipleValues() to work.
		if (firstFormControl==null) firstFormControl=formControls.iterator().next();
		return firstFormControl;
	}

	/** only called from FormFields class */
	void merge(final FormField formField) {
		if (formField.userValueCount>userValueCount) userValueCount=formField.userValueCount;
		allowsMultipleValues=allowsMultipleValues || formField.allowsMultipleValues;
		if (predefinedValues==null) {
			predefinedValues=formField.predefinedValues;
		} else if (formField.predefinedValues!=null) {
			for (String predefinedValue : predefinedValues) predefinedValues.add(predefinedValue);
		}
		for (FormControl formControl : formField.getFormControls()) formControls.add(formControl);
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -