blob: 838ad5b8ec5d08021332a7703229f91796d3c796 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.syncope.client.ui.commons.markup.html.form;
import com.googlecode.wicket.jquery.core.Options;
import com.googlecode.wicket.jquery.ui.JQueryUIBehavior;
import com.googlecode.wicket.jquery.ui.form.spinner.AjaxSpinner;
import com.googlecode.wicket.jquery.ui.form.spinner.SpinnerAdapter;
import com.googlecode.wicket.jquery.ui.form.spinner.SpinnerBehavior;
import java.io.Serializable;
import java.util.List;
import java.util.Optional;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.syncope.client.ui.commons.Constants;
import org.apache.syncope.client.ui.commons.ajax.form.IndicatorAjaxFormComponentUpdatingBehavior;
import org.apache.syncope.common.lib.Attributable;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.ResourceModel;
public final class AjaxSpinnerFieldPanel<T extends Number> extends FieldPanel<T> {
private static final long serialVersionUID = 6413819574530703577L;
private final Class<T> reference;
private final IModel<T> model;
private final Options options;
private SpinnerBehavior behavior;
private AjaxSpinnerFieldPanel(
final String id,
final String name,
final Class<T> reference,
final IModel<T> model,
final Options options,
final boolean enableOnChange) {
super(id, name, model);
field = new AjaxSpinner<>("spinner", model, options, reference) {
private static final long serialVersionUID = -3624755213720060594L;
@Override
public JQueryUIBehavior newWidgetBehavior(final String selector) {
behavior = new SpinnerBehavior(selector, new SpinnerAdapter());
behavior.setOptions(options);
return behavior;
}
};
if (enableOnChange && !isReadOnly()) {
field.add(new IndicatorAjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
private static final long serialVersionUID = -1107858522700306810L;
@Override
protected void onUpdate(final AjaxRequestTarget target) {
// nothing to do
}
});
}
add(field.setLabel(new ResourceModel(name, name)).setOutputMarkupId(true));
this.name = name;
this.model = model;
this.reference = reference;
this.options = options;
}
@Override
public AjaxSpinnerFieldPanel<T> setNewModel(final List<Serializable> list) {
setNewModel(new Model<>() {
private static final long serialVersionUID = 527651414610325237L;
@Override
public T getObject() {
T value = null;
if (list != null && !list.isEmpty()
&& list.get(0) != null && StringUtils.isNotBlank(list.get(0).toString())) {
value = reference.equals(Integer.class)
? reference.cast(NumberUtils.toInt(list.get(0).toString()))
: reference.equals(Long.class)
? reference.cast(NumberUtils.toLong(list.get(0).toString()))
: reference.equals(Short.class)
? reference.cast(NumberUtils.toShort(list.get(0).toString()))
: reference.equals(Float.class)
? reference.cast(NumberUtils.toFloat(list.get(0).toString()))
: reference.equals(byte.class)
? reference.cast(NumberUtils.toByte(list.get(0).toString()))
: reference.cast(NumberUtils.toDouble(list.get(0).toString()));
}
return value;
}
@Override
public void setObject(final T object) {
list.clear();
if (object != null) {
list.add(object.toString());
}
}
});
return this;
}
@SuppressWarnings("rawtypes")
@Override
public AjaxSpinnerFieldPanel<T> setNewModel(final ListItem item) {
field.setModel(new Model<>() {
private static final long serialVersionUID = 6799404673615637845L;
@Override
public T getObject() {
T number = null;
final Object obj = item.getModelObject();
if (obj != null && !obj.toString().isEmpty()) {
if (obj instanceof String) {
try {
number = reference.equals(Integer.class)
? reference.cast(Integer.valueOf((String) obj))
: reference.equals(Long.class)
? reference.cast(Long.valueOf((String) obj))
: reference.equals(Short.class)
? reference.cast(Short.valueOf((String) obj))
: reference.equals(Float.class)
? reference.cast(Float.valueOf((String) obj))
: reference.equals(byte.class)
? reference.cast(Byte.valueOf((String) obj))
: reference.cast(Double.valueOf((String) obj));
} catch (NumberFormatException e) {
LOG.error("While attempting to parse {}", obj, e);
}
} else if (obj instanceof Number) {
// Don't parse anything
number = reference.cast(obj);
}
}
return number;
}
@Override
@SuppressWarnings("unchecked")
public void setObject(final T object) {
item.setModelObject(Optional.ofNullable(object).map(Object::toString).orElse(null));
}
});
return this;
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public FieldPanel<T> setNewModel(final Attributable attributableTO, final String schema) {
field.setModel(new Model() {
private static final long serialVersionUID = -4214654722524358000L;
@Override
public Serializable getObject() {
List<String> values = attributableTO.getPlainAttr(schema).get().getValues();
if (!values.isEmpty()) {
return reference.equals(Integer.class)
? reference.cast(NumberUtils.toInt(values.get(0)))
: reference.equals(Long.class)
? reference.cast(NumberUtils.toLong(values.get(0)))
: reference.equals(Short.class)
? reference.cast(NumberUtils.toShort(values.get(0)))
: reference.equals(Float.class)
? reference.cast(NumberUtils.toFloat(values.get(0)))
: reference.equals(byte.class)
? reference.cast(NumberUtils.toByte(values.get(0)))
: reference.cast(NumberUtils.toDouble(values.get(0)));
}
return null;
}
@Override
public void setObject(final Serializable object) {
attributableTO.getPlainAttr(schema).get().getValues().clear();
if (object != null) {
attributableTO.getPlainAttr(schema).get().getValues().add(object.toString());
}
}
});
return this;
}
@Override
public AjaxSpinnerFieldPanel<T> clone() {
AjaxSpinnerFieldPanel<T> panel = new AjaxSpinnerFieldPanel<>(getId(), name, reference, model, options, false);
panel.setRequired(isRequired());
panel.setReadOnly(isReadOnly());
panel.setTitle(title);
if (isRequiredLabelAdded) {
panel.addRequiredLabel();
}
return panel;
}
@Override
public FieldPanel<T> setReadOnly(final boolean readOnly) {
super.setReadOnly(readOnly);
AjaxSpinner.class.cast(field).setEnabled(!readOnly);
options.set("disabled", readOnly);
if (behavior != null) {
behavior.setOptions(options);
}
return this;
}
public static class Builder<T extends Number> {
private final Options options = new Options();
private boolean enableOnChange = false;
public Builder<T> min(final T min) {
options.set("min", min);
return this;
}
public Builder<T> max(final T max) {
options.set("max", max);
return this;
}
public Builder<T> step(final T step) {
options.set("step", step);
return this;
}
public Builder<T> enableOnChange() {
enableOnChange = true;
return this;
}
public AjaxSpinnerFieldPanel<T> build(
final String id,
final String name,
final Class<T> reference,
final IModel<T> model) {
return new AjaxSpinnerFieldPanel<>(id, name, reference, model, options, enableOnChange);
}
}
}