/*
 * Copyright 2003 - 2017 The eFaps Team
 *
 * Licensed 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.efaps.ui.wicket.util;

import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.TreeMap;

import org.apache.commons.collections4.comparators.ComparatorChain;

/**
 * The Class DojoWrapper.
 */
public final class DojoWrapper
{

    /**
     * Instantiates a new dojo wrapper.
     */
    private DojoWrapper()
    {

    }

    /**
     * Require.
     *
     * @param _script the script
     * @param _classes the classes
     * @return the char sequence
     */
    public static CharSequence require(final CharSequence _script,
                                       final DojoClass... _classes)
    {
        final TreeMap<Double, DojoLayer> layers = new TreeMap<>();
        for (final DojoLayer layer : DojoLayer.values()) {
            long count = 0;
            for (final DojoClass dojoClass : _classes) {
                if (layer.getDojoClasses().contains(dojoClass)) {
                    count++;
                }
            }
            if (count > 0) {
                final double weight = (double) count / (double) layer.getDojoClasses().size();
                layers.put(weight, layer);
            }
        }
        return DojoWrapper.require(_script, layers.isEmpty() ? null
                        : layers.descendingMap().values().iterator().next().getName(), _classes);
    }

    /**
     * Require.
     *
     * @param _script the script
     * @param _layer the layer
     * @param _classes the classes
     * @return the char sequence
     */
    public static CharSequence require(final CharSequence _script,
                                       final String _layer,
                                       final DojoClass... _classes)
    {
        final StringBuilder ret = new StringBuilder();
        if (_layer != null) {
            ret.append("require(['").append(_layer).append("'],function() {\n");
        }

        ret.append("require([");
        final StringBuilder paras = new StringBuilder();
        boolean first = true;
        final List<DojoClass> libs = Arrays.asList(_classes);

        final ComparatorChain<DojoClass> comparator = new ComparatorChain<>();
        comparator.addComparator(new Comparator<DojoClass>()
        {

            @Override
            public int compare(final DojoClass _arg0,
                               final DojoClass _arg1)
            {
                return _arg0.getParameterName() == null && _arg1.getParameterName() == null || _arg0
                                .getParameterName() != null && _arg1.getParameterName() != null ? 0
                                                : _arg0.getParameterName() == null ? 1 : -1;
            }
        });
        comparator.addComparator(new Comparator<DojoClass>()
        {

            @Override
            public int compare(final DojoClass _arg0,
                               final DojoClass _arg1)
            {
                return _arg0.getClassName().compareTo(_arg1.getClassName());
            }
        });
        Collections.sort(libs, comparator);
        for (final DojoClass dojoLibs : libs) {
            if (first) {
                first = false;
            } else {
                ret.append(",");
                if (dojoLibs.getParameterName() != null) {
                    paras.append(",");
                }
            }
            ret.append("\"").append(dojoLibs.getClassName()).append("\"");
            if (dojoLibs.getParameterName() != null) {
                paras.append(dojoLibs.getParameterName());
            }
        }
        if (_script == null) {
            ret.append("]);");
        } else {
            ret.append("],").append(" function(").append(paras).append(") {\n").append(_script).append("});");
        }
        if (_layer != null) {
            ret.append("});");
        }
        return ret;
    }
}


/*
 * Copyright 2003 - 2014 The eFaps Team
 *
 * Licensed 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.
 *
 * Revision:        $Rev:1510 $
 * Last Changed:    $Date:2007-10-18 09:35:40 -0500 (Thu, 18 Oct 2007) $
 * Last Changed By: $Author:jmox $
 */
package org.efaps.ui.wicket.components.heading;

import org.apache.wicket.AttributeModifier;
import org.apache.wicket.Component;
import org.apache.wicket.markup.ComponentTag;
import org.apache.wicket.markup.head.IHeaderResponse;
import org.apache.wicket.markup.head.JavaScriptHeaderItem;
import org.apache.wicket.markup.html.WebComponent;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.Model;
import org.efaps.ui.wicket.behaviors.dojo.OnDojoReadyHeaderItem;
import org.efaps.ui.wicket.models.objects.UIHeading;
import org.efaps.ui.wicket.util.DojoClasses;
import org.efaps.ui.wicket.util.DojoWrapper;

/**
 * Class is used to render a panel containing a title for a page or a subtitle
 * inside a page.
 *
 * @author The eFaps Team
 * @version $Id:TitelPanel.java 1510 2007-10-18 14:35:40Z jmox $
 */
public class HeadingPanel
    extends Panel
{
    /**
     * Needed for serialization.
     */
    private static final long serialVersionUID = 1L;

    /**
     * Constructor.
     *
     * @param _wicketId wicket id for this component
     * @param _headingmodel model for this heading
     */
    public HeadingPanel(final String _wicketId,
                        final Model<UIHeading> _headingmodel)
    {
        super(_wicketId, _headingmodel);
        setOutputMarkupId(true);
        addComponents(_headingmodel);
    }

    @Override
    public void renderHead(final IHeaderResponse _response)
    {
        super.renderHead(_response);
        final StringBuilder js = new StringBuilder()
            .append("require([\"dojo/query\", \"dojo/dom\", \"dojo/dom-class\", \"dojo/NodeList-traverse\"],")
            .append("function(query, dom, domClass){\n")
            .append("var add = true;\n")
            .append("var node = dom.byId(_nodeID);\n")
            .append("domClass.toggle(node, \"eFapsCollapsedSection\");\n")
            .append("dom.byId(\"status_\" + _nodeID).value = domClass.contains(node, \"eFapsCollapsedSection\");")
            .append("query(node).nextAll().some(function(_node){\n")
            .append("if (add) {\n")
            .append("var x = query(\"div[class^='eFapsHeading']\", _node);\n")
            .append("if (x.length > 0){\n")
            .append("add = false;\n")
            .append("} else {\n")
            .append("domClass.toggle(_node, \"eFapsHiddenSection\");\n")
            .append("}\n")
            .append("}});\n")
            .append("});\n");

        final StringBuilder js2 = new StringBuilder().append("function toggleSection(_nodeID){")
            .append(DojoWrapper.require(js, DojoClasses.query, DojoClasses.dom, DojoClasses.domClass,
                        DojoClasses.NodeListTraverse)).append("}\n");

        _response.render(JavaScriptHeaderItem.forScript(js2, HeadingPanel.class.getName()));

        if (((UIHeading) getDefaultModelObject()).isCollapsible()
                        && ((UIHeading) getDefaultModelObject()).getCollapsed()) {
            final StringBuilder js3 = new StringBuilder();
            js3.append("toggleSection('").append(getMarkupId(true)).append("');");
                _response.render(OnDojoReadyHeaderItem.forScript(js3));
        }
    }

    /**
     * Method to add the Component to this Panel.
     *
     * @param _headingmodel model of the heading.
     */
    public void addComponents(final Model<UIHeading> _headingmodel)
    {
        final WebMarkupContainer container = new WebMarkupContainer("container");

        this.add(container);
        if (_headingmodel.getObject().getLevel() == 0) {
            container.add(AttributeModifier.replace("class", "eFapsFrameTitle"));
        } else {
            container.add(AttributeModifier.replace("class", "eFapsHeading" + _headingmodel.getObject().getLevel()));
        }
        container.add(new Label("heading", _headingmodel.getObject().getLabel()));

        final String toggleId = this.getMarkupId(true);
        final Component span = new WebComponent("toggle") {

            private static final long serialVersionUID = 1L;

            @Override
            protected void onComponentTag(final ComponentTag _tag)
            {
                super.onComponentTag(_tag);
                _tag.put("onclick", "toggleSection('" + toggleId + "');");
            }

            @Override
            public boolean isVisible()
            {
                return _headingmodel.getObject().getLevel() > 0 && _headingmodel.getObject().isCollapsible();
            }
        };
        container.add(span);

        final Component status = new WebComponent("status") {

            private static final long serialVersionUID = 1L;

            @Override
            protected void onComponentTag(final ComponentTag _tag)
            {
                super.onComponentTag(_tag);
                _tag.put("name", _headingmodel.getObject().getName());
                _tag.put("value", false);
            }

            @Override
            public boolean isVisible()
            {
                return _headingmodel.getObject().getLevel() > 0 && _headingmodel.getObject().isCollapsible();
            }
        };
        status.setMarkupId("status_" + toggleId);
        container.add(status);
    }
}


/*
 * Copyright 2003 - 2014 The eFaps Team
 *
 * Licensed 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.
 *
 * Revision:        $Rev$
 * Last Changed:    $Date$
 * Last Changed By: $Author$
 */

package org.efaps.ui.wicket.components.tree;

import java.util.Iterator;
import java.util.List;

import org.apache.wicket.extensions.markup.html.repeater.tree.ITreeProvider;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.efaps.ui.wicket.models.objects.UIStructurBrowser;

/**
 * TODO comment!
 *
 * @author The eFaps Team
 * @version $Id$
 */
public class StructurBrowserProvider
    implements ITreeProvider<UIStructurBrowser>
{
    /**
     *
     */
    private static final long serialVersionUID = 1L;

    /**
     * List of root nodes.
     */
    private final List<UIStructurBrowser> roots;

    /**
     * @param _model model
     */
    public StructurBrowserProvider(final IModel<UIStructurBrowser> _model)
    {
        this.roots = _model.getObject().getChildren();
    }

    @Override
    public Iterator<? extends UIStructurBrowser> getRoots()
    {
        return this.roots.iterator();
    }

    /**
     * Does the given object have children - note that this method may
     * return true even if {@link #getChildren(Object)}
     * returns an empty iterator.
     *
     * @param _node the node to check for children
     * @return {@code true} if node has children
     */
    @Override
    public boolean hasChildren(final UIStructurBrowser _node)
    {
        return _node.isParent() || _node.hasChildren();
    }

    /**
     * Get the children of the given node.
     *
     * @param _node node to get children for
     * @return children of node
     */
    @Override
    public Iterator<? extends UIStructurBrowser> getChildren(final UIStructurBrowser _node)
    {
        if (_node.isParent() && !_node.hasChildren()) {
            _node.addChildren();
        }
        return _node.getChildren().iterator();
    }

    /**
     * Callback used by the consumer of this tree provider to wrap objects retrieved from
     * {@link #getRoots()} or {@link #getChildren(Object)} with a model (usually a detachable one).
     *

     * Important note: The model must implement {@link Object#equals(Object)} and
     * {@link Object#hashCode()} !
     *
     * @param _object the object that needs to be wrapped
     *
     * @return the model representation of the object
     */
    @Override
    public IModel<UIStructurBrowser> model(final UIStructurBrowser _object)
    {
        return Model.of(_object);
    }

    /**
     * Detaches model after use. This is generally used to null out transient references that can be
     * re-attached later.
     */
    @Override
    public void detach()
    {
        // not implemented
    }
}


/*
 * Copyright 2003 - 2016 The eFaps Team
 *
 * Licensed 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.efaps.ui.wicket.models.field;

import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang3.EnumUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.wicket.Component;
import org.apache.wicket.model.Model;
import org.efaps.admin.datamodel.ui.UIValue;
import org.efaps.admin.dbproperty.DBProperties;
import org.efaps.admin.event.EventDefinition;
import org.efaps.admin.event.EventType;
import org.efaps.admin.event.Parameter.ParameterValues;
import org.efaps.admin.event.Return;
import org.efaps.admin.ui.field.Field;
import org.efaps.api.ui.IOption;
import org.efaps.db.Context;
import org.efaps.db.Instance;
import org.efaps.ui.wicket.behaviors.dojo.AutoCompleteBehavior;
import org.efaps.ui.wicket.components.values.LabelField;
import org.efaps.ui.wicket.models.AbstractInstanceObject;
import org.efaps.ui.wicket.models.field.AutoCompleteSettings.EditValue;
import org.efaps.ui.wicket.models.field.factories.AutoCompleteFactory;
import org.efaps.ui.wicket.models.field.factories.BitEnumUIFactory;
import org.efaps.ui.wicket.models.field.factories.BooleanUIFactory;
import org.efaps.ui.wicket.models.field.factories.DateTimeUIFactory;
import org.efaps.ui.wicket.models.field.factories.DateUIFactory;
import org.efaps.ui.wicket.models.field.factories.DecimalUIFactory;
import org.efaps.ui.wicket.models.field.factories.DecimalWithUoMFactory;
import org.efaps.ui.wicket.models.field.factories.EnumUIFactory;
import org.efaps.ui.wicket.models.field.factories.FormatedStringUIFactory;
import org.efaps.ui.wicket.models.field.factories.HRefFactory;
import org.efaps.ui.wicket.models.field.factories.IComponentFactory;
import org.efaps.ui.wicket.models.field.factories.JaxbUIFactory;
import org.efaps.ui.wicket.models.field.factories.LinkWithRangesUIFactory;
import org.efaps.ui.wicket.models.field.factories.NumberUIFactory;
import org.efaps.ui.wicket.models.field.factories.PasswordUIFactory;
import org.efaps.ui.wicket.models.field.factories.RateUIFactory;
import org.efaps.ui.wicket.models.field.factories.StringUIFactory;
import org.efaps.ui.wicket.models.field.factories.TypeUIFactory;
import org.efaps.ui.wicket.models.field.factories.UITypeFactory;
import org.efaps.ui.wicket.models.field.factories.UserUIFactory;
import org.efaps.ui.wicket.models.objects.AbstractUIModeObject;
import org.efaps.ui.wicket.models.objects.AbstractUIObject;
import org.efaps.util.EFapsException;
import org.efaps.util.cache.CacheReloadException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * TODO comment!
 *
 * @author The eFaps Team
 */
public abstract class AbstractUIField
    extends AbstractInstanceObject
    implements IPickable, IHidden, IFilterable, IAutoComplete, IUIElement
{
    /**
     * Needed for serialization.
     */
    private static final long serialVersionUID = 1L;

    /**
     * Logging instance used in this class.
     */
    private static final Logger LOG = LoggerFactory.getLogger(AbstractUIField.class);

    /**
     * The factories used to construct the components.
     */
    private static final Map<String, IComponentFactory> FACTORIES = new LinkedHashMap<>();

    static {
        AbstractUIField.FACTORIES.put(HRefFactory.get().getKey(), HRefFactory.get());
        AbstractUIField.FACTORIES.put(AutoCompleteFactory.get().getKey(), AutoCompleteFactory.get());
        AbstractUIField.FACTORIES.put(NumberUIFactory.get().getKey(), NumberUIFactory.get());
        AbstractUIField.FACTORIES.put(PasswordUIFactory.get().getKey(), PasswordUIFactory.get());
        AbstractUIField.FACTORIES.put(StringUIFactory.get().getKey(), StringUIFactory.get());
        AbstractUIField.FACTORIES.put(LinkWithRangesUIFactory.get().getKey(), LinkWithRangesUIFactory.get());
        AbstractUIField.FACTORIES.put(BooleanUIFactory.get().getKey(), BooleanUIFactory.get());
        AbstractUIField.FACTORIES.put(DateUIFactory.get().getKey(), DateUIFactory.get());
        AbstractUIField.FACTORIES.put(DateTimeUIFactory.get().getKey(), DateTimeUIFactory.get());
        AbstractUIField.FACTORIES.put(DecimalUIFactory.get().getKey(), DecimalUIFactory.get());
        AbstractUIField.FACTORIES.put(UserUIFactory.get().getKey(), UserUIFactory.get());
        AbstractUIField.FACTORIES.put(TypeUIFactory.get().getKey(), TypeUIFactory.get());
        AbstractUIField.FACTORIES.put(RateUIFactory.get().getKey(), RateUIFactory.get());
        AbstractUIField.FACTORIES.put(EnumUIFactory.get().getKey(), EnumUIFactory.get());
        AbstractUIField.FACTORIES.put(BitEnumUIFactory.get().getKey(), BitEnumUIFactory.get());
        AbstractUIField.FACTORIES.put(JaxbUIFactory.get().getKey(), JaxbUIFactory.get());
        AbstractUIField.FACTORIES.put(FormatedStringUIFactory.get().getKey(), FormatedStringUIFactory.get());
        AbstractUIField.FACTORIES.put(DecimalWithUoMFactory.get().getKey(), DecimalWithUoMFactory.get());
        AbstractUIField.FACTORIES.put(UITypeFactory.get().getKey(), UITypeFactory.get());
    }

    /**
     * Configuration of the related field.
     */
    private FieldConfiguration fieldConfiguration;

    /**
     * Parent Object.
     */
    private final AbstractUIModeObject parent;

    /**
     * UserInterface Value.
     */
    private UIValue value;

    /**
     * Picker related to this field.
     */
    private UIPicker picker;

    /**
     * Already added.
     */
    private boolean added;

    /**
     * Factory applied for this field.
     */
    private String factoryKey;

    /**
     * Value as shown for a picklist.
     */
    private String pickListValue;

    /**
     * Settings for the AutoComplete.
     */
    private AutoCompleteSettings autoCompleteSetting;

    /** The sort value. */
    private Comparable<?> sortValue;

    /** The hide. */
    private boolean hide;

    /**
     * @param _instanceKey key to the instance
     * @param _parent       parent object
     * @param _value        value
     * @throws EFapsException on error
     */
    public AbstractUIField(final AbstractUIModeObject _parent,
                           final String _instanceKey,
                           final UIValue _value)
        throws EFapsException
    {
        super(_instanceKey);
        this.parent = _parent;
        this.value = _value;
        this.fieldConfiguration = getNewFieldConfiguration();
    }

    /**
     * Getter method for the instance variable {@link #autoCompleteSetting}.
     *
     * @return value of instance variable {@link #autoCompleteSetting}
     */
    @Override
    public AutoCompleteSettings getAutoCompleteSetting()
    {
        if (this.autoCompleteSetting == null && isAutoComplete()) {
            this.autoCompleteSetting = new AutoCompleteSettings(getFieldConfiguration());

            final List<EventDefinition> events = getFieldConfiguration().getField().getEvents(
                            EventType.UI_FIELD_AUTOCOMPLETE);
            for (final EventDefinition event : events) {
                this.autoCompleteSetting.setMinInputLength(event.getProperty("MinInputLength") == null
                                ? 1 : Integer.valueOf(event.getProperty("MinInputLength")));
                this.autoCompleteSetting.setMaxChoiceLength(event.getProperty("MaxChoiceLength") == null
                                ? -1 : Integer.valueOf(event.getProperty("MaxChoiceLength")));
                this.autoCompleteSetting.setMaxValueLength(event.getProperty("MaxValueLength") == null
                                ? -1 : Integer.valueOf(event.getProperty("MaxValueLength")));
                if (event.getProperty("MaxResult") != null) {
                    this.autoCompleteSetting.setMaxResult(Integer.valueOf(event.getProperty("MaxResult")));
                }
                if (event.getProperty("HasDownArrow") != null) {
                    this.autoCompleteSetting
                                    .setHasDownArrow("true".equalsIgnoreCase(event.getProperty("HasDownArrow")));
                }
                if (event.getProperty("Required") != null) {
                    this.autoCompleteSetting
                                    .setRequired(!"false".equalsIgnoreCase(event.getProperty("Required")));
                }

                if (event.getProperty("AutoType") != null) {
                    this.autoCompleteSetting.setAutoType(EnumUtils.getEnum(AutoCompleteBehavior.Type.class,
                                    event.getProperty("AutoType")));
                }

                // add the ExtraParameter definitions
                final String ep = event.getProperty("ExtraParameter");
                if (ep != null) {
                    this.autoCompleteSetting.getExtraParameters().add(ep);
                }
                int i = 1;
                String keyTmp = "ExtraParameter" + String.format("%02d", i);
                while (event.getProperty(keyTmp) != null) {
                    this.autoCompleteSetting.getExtraParameters().add(event.getProperty(keyTmp));
                    i++;
                    keyTmp = "ExtraParameter" + String.format("%02d", i);
                }

                final String value4EditStr = event.getProperty("Value4Edit");
                if (value4EditStr != null) {
                    this.autoCompleteSetting.setValue4Edit(EditValue.valueOf(value4EditStr));
                }
            }
        }
        return this.autoCompleteSetting;
    }

    /**
     * Getter method for the instance variable {@link #parent}.
     *
     * @return value of instance variable {@link #parent}
     */
    @Override
    public AbstractUIModeObject getParent()
    {
        return this.parent;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean hasInstanceManager()
        throws EFapsException
    {
        return getParent() != null ? getParent().hasInstanceManager() : false;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Instance getInstanceFromManager()
        throws EFapsException
    {
        return getParent().getInstanceFromManager();
    }

    /**
     * Getter method for the instance variable {@link #value}.
     *
     * @return value of instance variable {@link #value}
     */
    public UIValue getValue()
    {
        return this.value;
    }

    /**
     * Setter method for instance variable {@link #value}.
     *
     * @param _value value for instance variable {@link #value}
     */
    public void setValue(final UIValue _value)
    {
        this.value = _value;
    }

    /**
     * Getter method for the instance variable {@link #fieldConfiguration}.
     *
     * @return value of instance variable {@link #fieldConfiguration}
     */
    public FieldConfiguration getFieldConfiguration()
    {
        return this.fieldConfiguration;
    }

    /**
     * @return the label for the UserInterface
     * @throws CacheReloadException on error
     */
    @Override
    public String getLabel()
        throws EFapsException
    {
        final String ret;
        if (getFieldConfiguration() != null) {
            ret = getFieldConfiguration().evalLabel(getValue(), getInstance());
        } else {
            ret = DBProperties.getProperty(FieldConfiguration.class.getName() + ".NoLabel");
        }
        return ret;
    }

    /**
     * Setter method for instance variable {@link #fieldConfiguration}.
     *
     * @param _fieldConfiguration value for instance variable {@link #fieldConfiguration}
     */

    protected void setFieldConfiguration(final FieldConfiguration _fieldConfiguration)
    {
        this.fieldConfiguration = _fieldConfiguration;
    }

    /**
     * @return a new FieldConfiguration
     * @throws EFapsException on error
     */
    protected FieldConfiguration getNewFieldConfiguration()
        throws EFapsException
    {
        final FieldConfiguration ret;
        if (getValue() == null) {
            ret = null;
        } else {
            ret = new FieldConfiguration(getValue().getField().getId());
        }
        return ret;
    }

    /**
     * @return is this value editable
     */
    public boolean editable()
    {
        return getValue().getField().isEditableDisplay(getParent().getMode());
    }

    /**
     * @return is this value editable
     */
    public boolean hidden()
    {
        return getValue().getField().isHiddenDisplay(getParent().getMode());
    }

    /**
     * @return the List of Factories used for this Field on construction of the component.
     */
    public Map<String, IComponentFactory> getFactories()
    {
        return AbstractUIField.FACTORIES;
    }

    /**
     * @param _wicketId wicket id
     * @return Component
     * @throws EFapsException on error
     */
    @Override
    public Component getComponent(final String _wicketId)
        throws EFapsException
    {
        Component ret = null;
        final IComponentFactory factory = getFactory();
        if (factory == null) {
            ret = new LabelField(_wicketId, Model.of("No Factory was applied successfully"),
                            this.fieldConfiguration, "NONE");
        } else {
            if (hidden()) {
                ret = factory.getHidden(_wicketId, this);
            } else if (editable()) {
                ret = factory.getEditable(_wicketId, this);
            } else {
                ret = factory.getReadOnly(_wicketId, this);
            }
        }
        if (ret == null) {
            throw new EFapsException(AbstractUIField.class, "factoryReturnsNoComponent",
                            getFieldConfiguration().getField());
        }
        return ret;
    }

    /**
     * Execute events.
     *
     * @param _eventType the event type
     * @param _others the others
     * @param _uiID2Oid the ui i d2 oid
     * @return the list< return>
     * @throws EFapsException on error
     */
    public List<Return> executeEvents(final EventType _eventType,
                                      final Object _others,
                                      final Map<String, String> _uiID2Oid)
        throws EFapsException
    {
        List<Return> ret = new ArrayList<>();
        final Field field = getFieldConfiguration().getField();
        if (field.hasEvents(_eventType)) {
            final Context context = Context.getThreadContext();
            final String[] contextoid = { getInstanceKey() };
            context.getParameters().put("oid", contextoid);
            ret = field.executeEvents(_eventType,
                            ParameterValues.INSTANCE, getInstance(),
                            ParameterValues.OTHERS, _others,
                            ParameterValues.PARAMETERS, context.getParameters(),
                            ParameterValues.CLASS, this,
                            ParameterValues.OIDMAP4UI, _uiID2Oid,
                            ParameterValues.CALL_INSTANCE, getParent().getInstance(),
                            ParameterValues.CALL_CMD, ((AbstractUIObject) getParent()).getCommand());
        }
        return ret;
    }

    /**
     * Getter method for the instance variable {@link #picker}.
     *
     * @return value of instance variable {@link #picker}
     */
    @Override
    public UIPicker getPicker()
    {
        return this.picker;
    }

    /**
     * Setter method for instance variable {@link #picker}.
     *
     * @param _picker value for instance variable {@link #picker}
     */
    public void setPicker(final UIPicker _picker)
    {
        this.picker = _picker;
    }

    /**
     * @return true if a picker is assigned else false;
     */
    public boolean hasPicker()
    {
        return getPicker() != null;
    }

    /**
     * Hide label.
     *
     * @return true, if successful
     */
    public boolean hideLabel()
    {
        return hasPicker() && getPicker().isButton() || getFieldConfiguration().isHideLabel();
    }

    @Override
    public String toString()
    {
        return new ToStringBuilder(this)
                        .append("Field", getFieldConfiguration().getField().getName())
                        .append("Value", getValue()).build();
    }

    @Override
    public IHidden setAdded(final boolean _added)
    {
        this.added = _added;
        return this;
    }

    @Override
    public boolean isAdded()
    {
        return this.added;
    }

    @Override
    public boolean belongsTo(final Long _fieldId)
    {
        return getFieldConfiguration().getField().getId() == _fieldId;
    }

    @Override
    public String getPickListValue()
        throws EFapsException
    {
        if (this.pickListValue == null) {
            this.pickListValue = getFactory().getPickListValue(this);
        }
        return this.pickListValue;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Comparable<?> getCompareValue()
    {
        Comparable<?> ret = null;
        try {
            if (this.sortValue == null) {
                ret = getFactory().getCompareValue(this);
            } else {
                ret = this.sortValue;
            }
        } catch (final EFapsException e) {
            LOG.error("Catched error", e);
        }
        return ret;
    }

    @Override
    public ISortable setCompareValue(final Object _object)
    {
        if (_object != null && _object instanceof Comparable) {
            this.sortValue = (Comparable<?>) _object;
        }
        return this;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public int compareTo(final ISortable _arg0)
    {
        return ObjectUtils.compare(getCompareValue(), _arg0.getCompareValue());
    }

    /**
     * Getter method for the instance variable {@link #factory}.
     *
     * @return value of instance variable {@link #factory}
     * @throws EFapsException on error
     */
    public IComponentFactory getFactory()
        throws EFapsException
    {
        if (getFactoryKey() == null) {
            for (final IComponentFactory factory : getFactories().values()) {
                if (factory.applies(this)) {
                    setFactory(factory);
                    break;
                }
            }
            if (getFactoryKey() == null) {
                LOG.error("Could not find factory for field '{}' in '{}'", getFieldConfiguration().getName(),
                                getFieldConfiguration().getField().getCollection().getName());
            }
        }
        return getFactories().get(getFactoryKey());
    }

    /**
     * Setter method for instance variable {@link #factory}.
     *
     * @param _factory value for instance variable {@link #factory}
     */
    public void setFactory(final IComponentFactory _factory)
    {
        this.factoryKey = _factory.getKey();
    }

    /**
     * Getter method for the instance variable {@link #factoryKey}.
     *
     * @return value of instance variable {@link #factoryKey}
     */
    public String getFactoryKey()
    {
        return this.factoryKey;
    }

    /**
     * Setter method for instance variable {@link #pickListValue}.
     *
     * @param _pickListValue value for instance variable {@link #pickListValue}
     */
    public void setPickListValue(final String _pickListValue)
    {
        this.pickListValue = _pickListValue;
    }

    /**
     * Checks if is auto complete.
     *
     * @return true, if is auto complete
     */
    @Override
    public boolean isAutoComplete()
    {
        return getFieldConfiguration().getField().hasEvents(EventType.UI_FIELD_AUTOCOMPLETE);
    }

    @Override
    public boolean isFieldUpdate()
    {
        return getFieldConfiguration().getField().hasEvents(EventType.UI_FIELD_UPDATE);
    }

    @Override
    public List<Return> getAutoCompletion(final String _input,
                                          final Map<String, String> _uiID2Oid)
        throws EFapsException
    {
        return executeEvents(EventType.UI_FIELD_AUTOCOMPLETE, _input, _uiID2Oid);
    }

    @Override
    public String getAutoCompleteValue()
        throws EFapsException
    {
        final Object val = getValue().getReadOnlyValue(getParent().getMode());
        return val == null ? null : String.valueOf(val);
    }

    @SuppressWarnings("unchecked")
    @Override
    public List<IOption> getTokens()
        throws EFapsException
    {
        final List<IOption> ret = new ArrayList<>();
        if (isAutoComplete() && getParent().isEditMode() && editable()
                        && getFieldConfiguration().getField().hasEvents(EventType.UI_FIELD_VALUE)) {
            final Object obj = getValue().getEditValue(getParent().getMode());
            if (obj instanceof List<?>) {
                ret.addAll((Collection<? extends IOption>) obj);
            }
        }
        return ret;
    }

    @Override
    public Instance getInstance()
        throws EFapsException
    {
        final Instance ret;
        // in case of an autocomplete in editmode give the chance to set the instance
        if (isAutoComplete() && getParent().isEditMode() && editable()
                        && getFieldConfiguration().getField().hasEvents(EventType.UI_FIELD_VALUE)) {
            getValue().getEditValue(getParent().getMode());
            ret = getValue().getInstance();
        } else {
            ret = super.getInstance();
        }
        return ret;
    }

    /**
     * Checks if is hide.
     *
     * @return the hide
     */
    public boolean isHide()
    {
        return this.hide;
    }

    /**
     * Sets the hide.
     *
     * @param _hide the new hide
     */
    public void setHide(final boolean _hide)
    {
        this.hide = _hide;
    }
}


/*
 * Copyright 2003 - 2016 The eFaps Team
 *
 * Licensed 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.efaps.ui.wicket.behaviors.dojo;

import org.apache.wicket.Component;
import org.apache.wicket.markup.ComponentTag;
import org.apache.wicket.markup.head.IHeaderResponse;
import org.efaps.ui.wicket.util.DojoClasses;

/**
 * TODO comment!
 *
 * @author The eFaps Team
 */
public class PopupMenuItemBehavior
    extends AbstractDojoBehavior
{
    /**
     * Needed for serialization.
     */
    private static final long serialVersionUID = 1L;

    /**
     * The tag of the related component must be set, so that a dojo
     * BorderContainer will be rendered.
     *
     * @param _component component this Behavior belongs to
     * @param _tag Tag to write to
     */
    @Override
    public void onComponentTag(final Component _component,
                               final ComponentTag _tag)
    {
        super.onComponentTag(_component, _tag);
        _tag.put("data-dojo-type", "dijit/PopupMenuItem");
    }

    /**
     * Render the links for the head.
     *
     * @param _component component the header will be rendered for
     * @param _response resonse to add
     */
    @Override
    public void renderHead(final Component _component,
                           final IHeaderResponse _response)
    {
        super.renderHead(_component, _response);
        _response.render(RequireHeaderItem.forClasses(DojoClasses.PopupMenuItem, DojoClasses.parser));
    }
}


/*
 * Copyright 2015-2016 Hewlett-Packard Development Company, L.P.
 * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
 */

package com.hp.autonomy.hod.client.config;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JavaType;
import com.hp.autonomy.hod.client.api.authentication.AuthenticationToken;
import com.hp.autonomy.hod.client.api.authentication.EntityType;
import com.hp.autonomy.hod.client.api.authentication.HodAuthenticationFailedException;
import com.hp.autonomy.hod.client.api.authentication.TokenType;
import com.hp.autonomy.hod.client.error.HodErrorException;
import com.hp.autonomy.hod.client.token.TokenProxy;
import com.hp.autonomy.hod.client.token.TokenProxyService;
import com.hp.autonomy.hod.client.token.TokenRepository;
import com.hp.autonomy.hod.client.token.TokenRepositoryException;
import retrofit.client.Response;

import java.io.IOException;
import java.io.InputStream;

/**
 * Makes a request to HP Haven OnDemand
 */
public class Requester<E extends EntityType, T extends TokenType> {

    private final TokenRepository tokenRepository;
    private final ResponseParser responseParser;
    private final TokenProxyService<? extends E, ? extends T> tokenProxyService;

    Requester(final TokenRepository tokenRepository, final ResponseParser responseParser, final TokenProxyService<? extends E, ? extends T> tokenProxyService) {
        this.tokenRepository = tokenRepository;
        this.responseParser = responseParser;
        this.tokenProxyService = tokenProxyService;
    }

    /**
     * Makes a request to HP Haven OnDemand using a TokenProxy provided by a {@link TokenProxyService}, converting the
     * response body to the type specified by the Class object.
     * @param returnType The desired type of the value returned by HP Haven OnDemand
     * @param backendCaller Makes the request to HP Haven OnDemand
     * @param <U> The desired type of the value returned by HP Haven OnDemand
     * @return An object representing the output from HP Haven OnDemand
     * @throws HodErrorException
     * @throws NullPointerException If a TokenProxyService has not been configured
     */
    public <U> U makeRequest(final Class<U> returnType, final BackendCaller<? super E, ? super T> backendCaller) throws HodErrorException {
        checkTokenProxyService();
        return makeRequest(tokenProxyService.getTokenProxy(), returnType, backendCaller);
    }

    /**
     * Makes a request to HP Haven OnDemand using a TokenProxy provided by a {@link TokenProxyService}, converting the
     * response body to the type specified by the type reference.
     * @param typeReference The desired type of the value returned by HP Haven OnDemand
     * @param backendCaller Makes the request to HP Haven OnDemand
     * @param <U> The desired type of the value returned by HP Haven OnDemand
     * @return An object representing the output from HP Haven OnDemand
     * @throws HodErrorException
     * @throws NullPointerException If a TokenProxyService has not been configured
     */
    public <U> U makeRequest(final TypeReference<U> typeReference, final BackendCaller<? super E, ? super T> backendCaller) throws HodErrorException {
        checkTokenProxyService();
        return makeRequest(tokenProxyService.getTokenProxy(), typeReference, backendCaller);
    }

    /**
     * Makes a request to HP Haven OnDemand using a TokenProxy provided by a {@link TokenProxyService}, returning the
     * response body as an input stream.
     * @param backendCaller Makes the request to HP Haven OnDemand
     * @return The response body
     * @throws HodErrorException
     * @throws NullPointerException If a TokenProxyService has not been configured
     */
    public InputStream makeRequest(final BackendCaller<? super E, ? super T> backendCaller) throws HodErrorException {
        checkTokenProxyService();
        return makeRequest(tokenProxyService.getTokenProxy(), backendCaller);
    }

    /**
     * Makes a request to HP Haven OnDemand using a TokenProxy provided by a {@link TokenProxyService}, converting the
     * response body to the type specified by the JavaType. This method does not guarantee that the type parameter U
     * represents the given JavaType. If possible, use one of the safe makeRequest methods instead.
     * @param type The desired type of the value returned by HP Haven OnDemand
     * @param backendCaller Makes the request to HP Haven OnDemand
     * @param <U> The desired type of the value returned by HP Haven OnDemand
     * @return An object representing the output from HP Haven OnDemand
     * @throws HodErrorException
     */
    public <U> U unsafeMakeRequest(final JavaType type, final BackendCaller<? super E, ? super T> backendCaller) throws HodErrorException {
        checkTokenProxyService();
        return unsafeMakeRequest(tokenProxyService.getTokenProxy(), type, backendCaller);
    }

    /**
     * Makes a request to HP Haven OnDemand, converting the response body to the type specified by the Class object.
     * @param tokenProxy The token proxy to use to make the request
     * @param returnType The desired type of the value returned by HP Haven OnDemand
     * @param backendCaller Makes the request to HP Haven OnDemand
     * @param <U> The desired type of the value returned by HP Haven OnDemand
     * @param <BE> The entity type of the token proxy
     * @param <BT> The token type of the token proxy
     * @return An object representing the output from HP Haven OnDemand
     * @throws HodErrorException
     */
    public <U, BE extends EntityType, BT extends TokenType> U makeRequest(
        final TokenProxy<BE, BT> tokenProxy,
        final Class<U> returnType,
        final BackendCaller<? super BE, ? super BT> backendCaller
    ) throws HodErrorException {
        return responseParser.parseResponse(tokenProxy, returnType, backendCaller.makeRequest(getAuthenticationToken(tokenProxy)));
    }

    /**
     * Makes a request to HP Haven OnDemand, converting the response body to the type specified by the type reference.
     * @param tokenProxy The token proxy to use to make the request
     * @param typeReference The desired type of the value returned by HP Haven OnDemand
     * @param backendCaller Makes the request to HP Haven OnDemand
     * @param <U> The desired type of the value returned by HP Haven OnDemand
     * @param <BE> The entity type of the token proxy
     * @param <BT> The token type of the token proxy
     * @return An object representing the output from HP Haven OnDemand
     * @throws HodErrorException
     */
    public <U, BE extends EntityType, BT extends TokenType> U makeRequest(
        final TokenProxy<BE, BT> tokenProxy,
        final TypeReference<U> typeReference,
        final BackendCaller<? super BE, ? super BT> backendCaller
    ) throws HodErrorException {
        return responseParser.parseResponse(tokenProxy, typeReference, backendCaller.makeRequest(getAuthenticationToken(tokenProxy)));
    }

    /**
     * Makes a request to HP Haven OnDemand, returning the response body as an input stream.
     * @param tokenProxy The token proxy to use to make the request
     * @param backendCaller Makes the request to HP Haven OnDemand
     * @param <BE> The entity type of the token proxy
     * @param <BT> The token type of the token proxy
     * @return The response body
     * @throws HodErrorException
     */
    public <BE extends EntityType, BT extends TokenType> InputStream makeRequest(
        final TokenProxy<BE, BT> tokenProxy,
        final BackendCaller<? super BE, ? super BT> backendCaller
    ) throws HodErrorException {
        return responseParser.parseResponse(tokenProxy, backendCaller.makeRequest(getAuthenticationToken(tokenProxy)));
    }

    /**
     * Makes a request to HP Haven OnDemand, converting the response body to the type specified by the JavaType. This
     * method does not guarantee that the type parameter U represents the given JavaType. If possible, use one of the
     * safe makeRequest methods instead.
     * @param tokenProxy The token proxy to use to make the request
     * @param type The desired type of the value returned by HP Haven OnDemand
     * @param backendCaller Makes the request to HP Haven OnDemand
     * @param <U> The desired type of the value returned by HP Haven OnDemand
     * @param <BE> The entity type of the token proxy
     * @param <BT> The token type of the token proxy
     * @return An object representing the output from HP Haven OnDemand
     * @throws HodErrorException
     */
    public <U, BE extends EntityType, BT extends TokenType> U unsafeMakeRequest(
        final TokenProxy<BE, BT> tokenProxy,
        final JavaType type,
        final BackendCaller<? super BE, ? super BT> backendCaller
    ) throws HodErrorException {
        return responseParser.unsafeParseResponse(tokenProxy, type, backendCaller.makeRequest(getAuthenticationToken(tokenProxy)));
    }

    private void checkTokenProxyService() {
        if (tokenProxyService == null) {
            throw new NullPointerException("A TokenProxyService has not been configured so a TokenProxy must be supplied");
        }
    }

    private <PE extends EntityType, PT extends TokenType> AuthenticationToken<PE, PT> getAuthenticationToken(final TokenProxy<PE, PT> tokenProxy) {
        final AuthenticationToken<PE, PT> authenticationToken;

        try {
            authenticationToken = tokenRepository.get(tokenProxy);

            if (authenticationToken == null) {
                throw new HodAuthenticationFailedException("No token found - perhaps it has expired", tokenProxy);
            }
            else if (authenticationToken.hasExpired()) {
                // this token is no good, so why hang onto it
                tokenRepository.remove(tokenProxy);

                throw new HodAuthenticationFailedException("Token has expired", tokenProxy);
            }
        } catch (final IOException e) {
            throw new TokenRepositoryException(e);
        }

        return authenticationToken;
    }

    /**
     * Exchanges an AuthenticationToken for a response from HP Haven OnDemand.
     * @param <E> The most general authentication entity type which this backend caller accepts
     * @param <T> The most general authentication token type which this backend caller accepts
     */
    @FunctionalInterface
    public interface BackendCaller<E extends EntityType, T extends TokenType> {

        /**
         * Makes a request to HP Haven OnDemand
         * @param authenticationToken The token with which to make the request
         * @return A response from HP Haven OnDemand
         * @throws HodErrorException
         */
        Response makeRequest(final AuthenticationToken<? extends E, ? extends T> authenticationToken) throws HodErrorException;

    }
}


/*
 * Copyright 2015-2016 Hewlett-Packard Development Company, L.P.
 * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
 */

package com.hp.autonomy.hod.client.converter;

import com.fasterxml.jackson.core.JsonParseException;
import retrofit.converter.ConversionException;
import retrofit.converter.Converter;
import retrofit.mime.TypedInput;
import retrofit.mime.TypedOutput;
import retrofit.mime.TypedString;

import java.lang.reflect.Type;

/**
 * {@link retrofit.converter.Converter} implementation that respects the {@link DoNotConvert}
 * annotation.
 */
public class HodConverter implements Converter {

    private final Converter converter;

    /**
     * Creates a new HodConverter
     * @param converter Delegate converter which will do most of the work
     */
    public HodConverter(final Converter converter) {
        this.converter = converter;
    }

    /**
     * Returns the object returned by calling fromBody on the underlying converter
     */
    @Override
    public Object fromBody(final TypedInput body, final Type type) throws ConversionException {
        try {
            return converter.fromBody(body, type);
        } catch(final ConversionException e) {
            if(e.getCause() instanceof JsonParseException) {
                throw new HodUnavailableException(e.getCause());
            } else {
                throw e;
            }

        }
    }

    /**
     * If object is annotated with {@link DoNotConvert}, returns a String
     * representation of the object. Otherwise returns the object returned by calling toBody on the underlying converter
     */
    @Override
    public TypedOutput toBody(final Object object) {
        if (object.getClass().isAnnotationPresent(DoNotConvert.class)) {
            return new TypedString(object.toString());
        }
        else {
            return converter.toBody(object);
        }
    }
}


/*
 * Copyright 2003 - 2016 The eFaps Team
 *
 * Licensed 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.efaps.ui.wicket.behaviors;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.wicket.AttributeModifier;
import org.apache.wicket.Component;
import org.apache.wicket.Page;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.form.AjaxFormSubmitBehavior;
import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
import org.apache.wicket.feedback.FeedbackCollector;
import org.apache.wicket.feedback.FeedbackMessage;
import org.apache.wicket.markup.head.IHeaderResponse;
import org.apache.wicket.markup.html.form.ValidationErrorFeedback;
import org.apache.wicket.model.IModel;
import org.efaps.admin.event.EventType;
import org.efaps.admin.event.Return;
import org.efaps.admin.event.Return.ReturnValues;
import org.efaps.ui.wicket.components.modalwindow.ModalWindowContainer;
import org.efaps.ui.wicket.components.values.ErrorMessageResource;
import org.efaps.ui.wicket.components.values.IFieldConfig;
import org.efaps.ui.wicket.models.field.AbstractUIField;
import org.efaps.ui.wicket.models.objects.AbstractUIPageObject;
import org.efaps.ui.wicket.pages.content.AbstractContentPage;
import org.efaps.ui.wicket.pages.dialog.DialogPage;
import org.efaps.ui.wicket.resources.AbstractEFapsHeaderItem;
import org.efaps.ui.wicket.resources.EFapsContentReference;
import org.efaps.ui.wicket.util.EFapsKey;
import org.efaps.util.EFapsException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * TODO comment!
 *
 * @author The eFaps Team
 */
public class AjaxFieldUpdateBehavior
    extends AjaxFormSubmitBehavior
{
    /**
     * Reference to the javascript.
     */
    public static final EFapsContentReference JS = new EFapsContentReference(AjaxFieldUpdateBehavior.class,
                                                                             "FieldUpdate.js");

    /**
     * Logger for this class.
     */
    private static final Logger LOG = LoggerFactory.getLogger(AjaxFieldUpdateBehavior.class);

    /**
     * Needed for serialization.
     */
    private static final long serialVersionUID = 1L;

    /**
     * Model that will be used on submit (if not null).
     */
    private final IModel<?> model;

    /**
     * Is the callback beeing executed from dojo.
     */
    private boolean dojoCall = false;

    /**
     * Activate/Deactivate ErrorHandling.
     */
    private final boolean errorHandling;

    /**
     * @param _event event that this behavior should be executed on;
     */
    public AjaxFieldUpdateBehavior(final String _event)
    {
        this(_event, null);
    }

    /**
     * @param _event event that this behavior should be executed on;
     * @param _model model that willbe used on submit
     */
    public AjaxFieldUpdateBehavior(final String _event,
                                   final IModel<?> _model)
    {
        this(_event, _model, true);
    }

    /**
     * Instantiates a new ajax field update behavior.
     *
     * @param _event event that this behavior should be executed on;
     * @param _model model that willbe used on submit
     * @param _errorHandling the error handling
     */
    public AjaxFieldUpdateBehavior(final String _event,
                                   final IModel<?> _model,
                                   final boolean _errorHandling)
    {
        super(_event);
        this.model = _model;
        this.errorHandling = _errorHandling;
    }

    /**
     * Render to the web response the eFapsContentReference.
     *
     * @param _response Response object
     */@Override
    public void renderHead(final Component _component,
                           final IHeaderResponse _response)
    {
        super.renderHead(_component, _response);
        _response.render(AbstractEFapsHeaderItem.forJavaScript(AjaxFieldUpdateBehavior.JS));
    }

    /**
     * Default means nothing is done on error.
     *
     * @see org.apache.wicket.ajax.form.AjaxFormSubmitBehavior#onError(org.apache.wicket.ajax.AjaxRequestTarget)
     * @param _target AjaxRequestTarget
     */
    @Override
    protected void onError(final AjaxRequestTarget _target)
    {
        if (this.errorHandling) {
            final FeedbackCollector collector = new FeedbackCollector(getForm().getPage());
            final List<FeedbackMessage> msgs = collector.collect();
            final StringBuilder html = new StringBuilder()
                            .append("
");
            for (final FeedbackMessage msg : msgs) {
                msg.getReporter().add(AttributeModifier.append("class", "invalid"));
                _target.add(msg.getReporter());
                Serializable warn = null;
                if (msg.getMessage() instanceof ValidationErrorFeedback) {
                    // look if a message was set
                    warn = ((ValidationErrorFeedback) msg.getMessage()).getMessage();
                    // still no message, create one
                    if (warn == null) {
                        warn = ((ValidationErrorFeedback) msg.getMessage()).getError().getErrorMessage(
                                        new ErrorMessageResource());
                    }
                }
                String label = "";
                if (msg.getReporter() instanceof IFieldConfig) {
                    label = ((IFieldConfig) msg.getReporter()).getFieldConfig().getLabel();
                }
                html.append("
").append(label).append(":	")
                                .append(warn).append("
");
            }
            html.append("
");

            final ModalWindowContainer modal = ((AbstractContentPage) getComponent().getPage()).getModal();

            modal.setInitialWidth(350);
            modal.setInitialHeight(200);

            modal.setPageCreator(new ModalWindow.PageCreator()
            {

                private static final long serialVersionUID = 1L;

                @Override
                public Page createPage()
                {
                    return new DialogPage(((AbstractContentPage) getComponent().getPage()).getPageReference(),
                                    html.toString(), true, false);
                }
            });
            modal.show(_target);
        }
    }

    @Override
    public boolean getDefaultProcessing()
    {
        final boolean ret;
        if (this.errorHandling) {
            ret = super.getDefaultProcessing();
        } else {
            ret = false;
        }
        return ret;
    }

    /**
     * @see org.apache.wicket.ajax.form.AjaxFormSubmitBehavior#onSubmit(org.apache.wicket.ajax.AjaxRequestTarget)
     * @param _target AjaxRequestTarget
     */
    @Override
    protected void onSubmit(final AjaxRequestTarget _target)
    {
        final Object uiObject;
        if (this.model == null) {
            uiObject = getComponent().getDefaultModelObject();
        } else {
            uiObject = this.model.getObject();
        }
        final List<Map<String, Object>> values = new ArrayList<Map<String, Object>>();

        try {
            final AbstractUIPageObject pageObject = (AbstractUIPageObject) getComponent().getPage()
                            .getDefaultModelObject();
            final Map<String, String> uiID2Oid = pageObject == null ? null : pageObject.getUiID2Oid();
            final List<Return> returns = ((AbstractUIField) uiObject).executeEvents(EventType.UI_FIELD_UPDATE,
                            getComponent().getMarkupId(), uiID2Oid);
            for (final Return aReturn : returns) {
                final Object ob = aReturn.get(ReturnValues.VALUES);
                if (ob instanceof List) {
                    @SuppressWarnings("unchecked")
                    final List<Map<String, Object>> list = (List<Map<String, Object>>) ob;
                    values.addAll(list);
                }
            }
        } catch (final EFapsException e) {
            AjaxFieldUpdateBehavior.LOG.error("onSubmit", e);
        }

        final StringBuilder js = new StringBuilder();
        int i = 0;
        for (final Map<String, Object> map : values) {
            if (map.size() > 0) {
                final boolean useId = map.containsKey(EFapsKey.FIELDUPDATE_USEID.getKey());
                final boolean useIdx = map.containsKey(EFapsKey.FIELDUPDATE_USEIDX.getKey());
                for (final String keyString : map.keySet()) {
                    // if the map contains a key that is not defined in this class
                    // it is assumed to be the name of a field
                    if (!EFapsKey.FIELDUPDATE_JAVASCRIPT.getKey().equals(keyString)
                                    && !EFapsKey.FIELDUPDATE_USEID.getKey().equals(keyString)
                                    && !EFapsKey.FIELDUPDATE_USEIDX.getKey().equals(keyString)) {
                        js.append("eFapsSetFieldValue(");
                        if (useId || values.size() == 1 && !useIdx) {
                            js.append("'").append(map.get(EFapsKey.FIELDUPDATE_USEID.getKey()) == null
                                            ? getComponentMarkupId()
                                            : map.get(EFapsKey.FIELDUPDATE_USEID.getKey())).append("'");
                        } else {
                            js.append(map.get(EFapsKey.FIELDUPDATE_USEIDX.getKey()) == null ? i
                                            : map.get(EFapsKey.FIELDUPDATE_USEIDX.getKey()));
                        }
                        js.append(",'").append(keyString).append("',");
                        final Object value = map.get(keyString);
                        final String strValue;
                        final String strLabel;
                        if (value instanceof String[] && ((String[]) value).length == 2) {
                            strValue = ((String[]) value)[0];
                            strLabel = ((String[]) value)[1];
                        } else {
                            strValue = String.valueOf(value);
                            strLabel = null;
                        }
                        js.append(strValue.contains("Array(") ? "" : "'")
                            .append(strValue)
                            .append(strValue.contains("Array(") ? "" : "'");
                        if (strLabel != null) {
                            js.append(",'").append(strLabel).append("'");
                        }
                        js.append(");");
                    }
                }
            }
            if (map.containsKey(EFapsKey.FIELDUPDATE_JAVASCRIPT.getKey())) {
                js.append(map.get(EFapsKey.FIELDUPDATE_JAVASCRIPT.getKey()));
            }
            i++;
        }
        _target.appendJavaScript(js.toString());
    }

    /**
     * Method to get the ComponentMarkupId.
     *
     * @return markup id of the component.
     */
    protected String getComponentMarkupId()
    {
        return getComponent().getMarkupId();
    }

    /**
     * @return charequence
     */
    public CharSequence getCallbackScript4Dojo()
    {
        return super.getCallbackScript(getComponent());
    }

    @Override
    protected CharSequence getCallbackScript(final Component _component)
    {
        final CharSequence ret;
        if (isDojoCall()) {
            ret = "";
        } else {
            ret = super.getCallbackScript(_component);
        }
        return ret;
    }

    /**
     * Getter method for the instance variable {@link #dojoCall}.
     *
     * @return value of instance variable {@link #dojoCall}
     */
    public boolean isDojoCall()
    {
        return this.dojoCall;
    }

    /**
     * Setter method for instance variable {@link #dojoCall}.
     *
     * @param _dojoCall value for instance variable {@link #dojoCall}
     */
    public void setDojoCall(final boolean _dojoCall)
    {
        this.dojoCall = _dojoCall;
    }
}


/*
 * Copyright 2003 - 2016 The eFaps Team
 *
 * Licensed 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.efaps.ui.wicket.models.field.factories;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.NumberFormat;

import org.apache.wicket.Component;
import org.apache.wicket.model.Model;
import org.efaps.admin.datamodel.ui.DecimalUI;
import org.efaps.db.Context;
import org.efaps.ui.wicket.components.values.NumberField;
import org.efaps.ui.wicket.models.field.AbstractUIField;
import org.efaps.util.EFapsException;

/**
 * TODO comment!
 *
 * @author The eFaps Team
 */
@SuppressWarnings("checkstyle:abstractclassname")
public final class DecimalUIFactory
    extends StringUIFactory
{

    /**
     * Factory Instance.
     */
    private static DecimalUIFactory FACTORY;

    /**
     * Singelton.
     */
    private DecimalUIFactory()
    {
    }

    @Override
    public Component getEditable(final String _wicketId,
                                 final AbstractUIField _uiField)
        throws EFapsException
    {
        Component ret = null;
        if (applies(_uiField)) {
            ret = new NumberField(_wicketId, Model.of(_uiField), _uiField.getFieldConfiguration());
        }
        return ret;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean applies(final AbstractUIField _abstractUIField)
        throws EFapsException
    {
        return _abstractUIField.getValue().getUIProvider() instanceof DecimalUI;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected String getReadOnlyValue(final AbstractUIField _abstractUIField)
        throws EFapsException
    {
        String strValue = "";
        final Object valueTmp = _abstractUIField.getValue()
                        .getReadOnlyValue(_abstractUIField.getParent().getMode());
        if (valueTmp instanceof Number) {
            final DecimalFormat formatter = (DecimalFormat) NumberFormat.getInstance(Context.getThreadContext()
                            .getLocale());
            if (_abstractUIField.getValue().getAttribute() != null) {
                formatter.setMaximumFractionDigits(_abstractUIField.getValue().getAttribute().getScale());
            }
            if (valueTmp instanceof BigDecimal) {
                final int scale = ((BigDecimal) valueTmp).scale();
                if (formatter.getMinimumFractionDigits() < scale) {
                    formatter.setMinimumFractionDigits(scale);
                }
            }
            strValue = formatter.format(valueTmp);
        }
        return strValue;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getKey()
    {
        return DecimalUIFactory.class.getName();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getPickListValue(final AbstractUIField _uiField)
        throws EFapsException
    {
        return getReadOnlyValue(_uiField);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Comparable<?> getCompareValue(final AbstractUIField _uiField)
        throws EFapsException
    {
        return (Comparable<?>) _uiField.getValue().getReadOnlyValue(_uiField.getParent().getMode());
    }

    /**
     * @return IComponentFactory instance
     */
    public static IComponentFactory get()
    {
        if (DecimalUIFactory.FACTORY == null) {
            DecimalUIFactory.FACTORY = new DecimalUIFactory();
        }
        return DecimalUIFactory.FACTORY;
    }
}


/*
 * Copyright 2003 - 2018 The eFaps Team
 *
 * Licensed 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.efaps.ui.wicket;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.ServiceLoader;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import javax.servlet.http.HttpServletRequest;

import org.apache.wicket.Application;
import org.apache.wicket.Component;
import org.apache.wicket.RestartResponseAtInterceptPageException;
import org.apache.wicket.Session;
import org.apache.wicket.application.AbstractClassResolver;
import org.apache.wicket.application.CompoundClassResolver;
import org.apache.wicket.application.DefaultClassResolver;
import org.apache.wicket.authorization.Action;
import org.apache.wicket.authorization.IAuthorizationStrategy;
import org.apache.wicket.event.IEvent;
import org.apache.wicket.javascript.DefaultJavaScriptCompressor;
import org.apache.wicket.markup.html.IPackageResourceGuard;
import org.apache.wicket.markup.html.SecurePackageResourceGuard;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.page.XmlPartialPageUpdate;
import org.apache.wicket.protocol.http.WebApplication;
import org.apache.wicket.protocol.ws.api.event.WebSocketTextPayload;
import org.apache.wicket.protocol.ws.api.message.TextMessage;
import org.apache.wicket.request.Request;
import org.apache.wicket.request.Response;
import org.apache.wicket.request.component.IRequestableComponent;
import org.apache.wicket.request.cycle.RequestCycle;
import org.apache.wicket.request.http.WebRequest;
import org.apache.wicket.request.mapper.parameter.PageParameters;
import org.apache.wicket.request.resource.IResource;
import org.apache.wicket.resource.JQueryResourceReference;
import org.apache.wicket.util.lang.Bytes;
import org.apache.wicket.util.string.AppendingStringBuffer;
import org.efaps.admin.AppConfigHandler;
import org.efaps.admin.program.esjp.EFapsClassLoader;
import org.efaps.api.background.IJob;
import org.efaps.api.ui.ILoginProvider;
import org.efaps.db.Context;
import org.efaps.jaas.AppAccessHandler;
import org.efaps.ui.filter.AbstractFilter;
import org.efaps.ui.wicket.background.ExecutionBridge;
import org.efaps.ui.wicket.background.JobContext;
import org.efaps.ui.wicket.background.JobRunnable;
import org.efaps.ui.wicket.behaviors.KeepAliveBehavior;
import org.efaps.ui.wicket.behaviors.dojo.AutoCompleteBehavior.ACAjaxRequestTarget;
import org.efaps.ui.wicket.connectionregistry.RegistryManager;
import org.efaps.ui.wicket.pages.error.UnexpectedErrorPage;
import org.efaps.ui.wicket.pages.login.LoginPage;
import org.efaps.ui.wicket.pages.main.MainPage;
import org.efaps.ui.wicket.pages.pivot.JsonResponsePage;
import org.efaps.ui.wicket.request.EFapsRequest;
import org.efaps.ui.wicket.request.EFapsRequestCycleListener;
import org.efaps.ui.wicket.request.EFapsResourceAggregator;
import org.efaps.ui.wicket.util.Configuration;
import org.efaps.ui.wicket.util.Configuration.ConfigAttribute;
import org.efaps.util.EFapsException;
import org.efaps.util.RandomUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * This Class presents the WebApplication for eFaps using the Wicket-Framework.
 * <br/>
 * It is the first class which is instantiated from the WicketServlet. Here the
 * Sessions for each user a created and basic Settings are set.
 *
 * @author The eFaps Team
 */
public class EFapsApplication
    extends WebApplication
{

    /** The max inactive interval. */
    private static int MAXINACTIVEINTERVAL = 0;

    /**
     * Logger for this class.
     */
    private static final Logger LOG = LoggerFactory.getLogger(EFapsApplication.class);

    /** The executor service. */
    private final ExecutorService executorService = new ThreadPoolExecutor(10, 10, 0L, TimeUnit.MILLISECONDS,
                    new LinkedBlockingQueue<Runnable>(), (ThreadFactory) _r -> {
                        final Thread ret = Executors.defaultThreadFactory().newThread(_r);
                        ret.setName("eFaps-Process-" + ret.getId());
                        ret.setContextClassLoader(EFapsClassLoader.getInstance());
                        ret.setUncaughtExceptionHandler((_thread,
                                                         _throwable) -> {
                            EFapsApplication.LOG.error("Caught error from Thread '{}'", _thread.getName());
                            EFapsApplication.LOG.error("->", _throwable);
                        });
                        return ret;
                    });

    /** The loginProviders. */
    private final List<ILoginProvider> loginProviders = new ArrayList<>();

    /**
     * @see org.apache.wicket.Application#getHomePage()
     * @return Class of the main page
     */
    @Override
    public Class<MainPage> getHomePage()
    {
        return MainPage.class;
    }

    /**
     * @see org.apache.wicket.protocol.http.WebApplication#init()
     */
    @Override
    protected void init()
    {
        super.init();

        final String appKey = getInitParameter(AbstractFilter.INITPARAM_APP_KEY);
        final String loginRolesTmp = getInitParameter(AbstractFilter.INITPARAM_LOGIN_ROLES);
        final Set<UUID> temp = new HashSet<>();
        if (loginRolesTmp != null) {
            final String[] loginRolesAr = loginRolesTmp.split(",");
            for (final String loginRole : loginRolesAr) {
                temp.add(UUID.fromString(loginRole));
            }
        }
        AppAccessHandler.init(appKey, temp);

        final Map<String, String> map = new HashMap<>();
        for (final AppConfigHandler.Parameter param : AppConfigHandler.Parameter.values()) {
            final String configTmp = getInitParameter(param.getKey());
            if (configTmp != null) {
                map.put(param.getKey(), configTmp);
            }
        }
        if (!map.containsKey(AppConfigHandler.Parameter.TEMPFOLDER.getKey())) {
            map.put(AppConfigHandler.Parameter.TEMPFOLDER.getKey(), getStoreSettings().getFileStoreFolder().toURI()
                            .toString());
        }
        AppConfigHandler.init(map);

        getJavaScriptLibrarySettings().setJQueryReference(JQueryResourceReference.getV3());

        getApplicationSettings().setPageExpiredErrorPage(MainPage.class);
        getApplicationSettings().setInternalErrorPage(UnexpectedErrorPage.class);

        final CompoundClassResolver resolver = new CompoundClassResolver();
        resolver.add(new DefaultClassResolver());
        resolver.add(new AbstractClassResolver()
        {

            @Override
            public ClassLoader getClassLoader()
            {
                return EFapsClassLoader.getInstance();
            }

        });
        getApplicationSettings().setClassResolver(resolver);

        getApplicationSettings().setUploadProgressUpdatesEnabled(true);

        getDebugSettings().setAjaxDebugModeEnabled(false);
        getDebugSettings().setDevelopmentUtilitiesEnabled(false);

        setPageManagerProvider(new EFapsPageManagerProvider(this));

        getStoreSettings().setMaxSizePerSession(Bytes.megabytes(Configuration.getAttributeAsInteger(
                        ConfigAttribute.STORE_MAXSIZEPERSESSION)));
        getStoreSettings().setInmemoryCacheSize(Configuration.getAttributeAsInteger(
                        ConfigAttribute.STORE_INMEMORYCACHE));

        getMarkupSettings().setStripWicketTags(true);
        getMarkupSettings().setStripComments(true);
        getMarkupSettings().setCompressWhitespace(true);
        getMarkupSettings().setAutomaticLinking(false);

        getRequestCycleSettings().setGatherExtendedBrowserInfo(true);
        getRequestCycleListeners().add(new EFapsRequestCycleListener());
        getRequestLoggerSettings().setRequestLoggerEnabled(false);

        getSecuritySettings().setAuthorizationStrategy(new EFapsFormBasedAuthorizationStartegy());

        getResourceSettings().setJavaScriptCompressor(new DefaultJavaScriptCompressor());

        // allow svg resources
        final IPackageResourceGuard guard = getResourceSettings().getPackageResourceGuard();
        if (guard instanceof SecurePackageResourceGuard) {
            ((SecurePackageResourceGuard) guard).addPattern("+*.svg");
            ((SecurePackageResourceGuard) guard).addPattern("+*.json");
        }

        setHeaderResponseDecorator(_response -> new EFapsResourceAggregator(_response));
        getRequestCycleSettings().addResponseFilter(_responseBuffer -> {
            final AppendingStringBuffer ret;
            if (RequestCycle.get().getActiveRequestHandler() instanceof ACAjaxRequestTarget) {
                ret = new AppendingStringBuffer().append(_responseBuffer.subSequence(0, _responseBuffer.length()
                                - XmlPartialPageUpdate.END_ROOT_ELEMENT.length()));
            } else {
                ret = _responseBuffer;
            }
            return ret;
        });

        final ServiceLoader<ILoginProvider> serviceLoaderLogins = ServiceLoader.load(ILoginProvider.class);
        for (final ILoginProvider loginProvider : serviceLoaderLogins) {
            LOG.info("[{}] registered: {}", getName(), loginProvider);
            this.loginProviders.add(loginProvider);
        }
        mountPage("/" + RandomUtil.randomAlphabetic(16), JsonResponsePage.class);
    }

    /**
     * @see org.apache.wicket.protocol.http.WebApplication#newSession(org.apache.wicket.Request,
     *      org.apache.wicket.Response)
     * @param _request the request
     * @param _response the response
     * @return a new Session for the request
     */
    @Override
    public Session newSession(final Request _request,
                              final Response _response)
    {
        return new EFapsSession(_request, getApplicationKey());
    }

    /**
     * @param _servletRequest request
     * @param _filterPath path
     *
     * @return a new WebRequest
     */
    @Override
    public WebRequest newWebRequest(final HttpServletRequest _servletRequest,
                                    final String _filterPath)
    {
        if (EFapsApplication.MAXINACTIVEINTERVAL == 0) {
            final int interval = _servletRequest.getSession().getMaxInactiveInterval();
            if (interval == 0) {
                EFapsApplication.MAXINACTIVEINTERVAL = -1;
            } else {
                EFapsApplication.MAXINACTIVEINTERVAL = interval;
            }
        }
        return new EFapsRequest(_servletRequest, _filterPath);
    }

    @Override
    public void onEvent(final IEvent<?> _event)
    {
        if (_event.getPayload() instanceof WebSocketTextPayload) {
            final WebSocketTextPayload wsEvent = (WebSocketTextPayload) _event.getPayload();
            if (wsEvent != null) {
                final TextMessage msg = wsEvent.getMessage();
                if (KeepAliveBehavior.MSG.equals(msg.getText())) {
                    RegistryManager.registerKeepAlive(Session.get());
                    _event.stop();
                }
            }
        }
    }

    @Override
    protected void onDestroy()
    {
        this.executorService.shutdown();
        try {
            if (!this.executorService.awaitTermination(2, TimeUnit.SECONDS)) {
                this.executorService.shutdownNow();
            }
        } catch (final InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * Launch a job.
     *
     * @param _job the _job
     * @param _jobName the _job name
     * @return the execution bridge
     * @throws EFapsException on error
     */
    public ExecutionBridge launch(final IJob _job,
                                  final String _jobName)
        throws EFapsException
    {
        // we are on WEB thread so services should be normally injected.
        final ExecutionBridge bridge = new ExecutionBridge();
        // register bridge on session
        if (_jobName == null) {
            bridge.setJobName("EFapsJob-" + EFapsSession.get().countJobs() + 1 + "-"
                            + RandomUtil.randomAlphanumeric(4));
        } else {
            bridge.setJobName(_jobName);
        }
        bridge.setJobContext(new JobContext().setUserName(Context.getThreadContext().getPerson().getName()).setLocale(
                        Context.getThreadContext().getLocale()).setCompanyUUID(Context.getThreadContext().getCompany()
                                        .getUUID()));

        EFapsSession.get().addExecutionBridge(bridge);
        // run the task
        this.executorService.execute(new JobRunnable(_job, bridge));
        return bridge;
    }

    /**
     * Gets the loginProviders.
     *
     * @return the loginProviders
     */
    public List<ILoginProvider> getLoginProviders()
    {
        return Collections.unmodifiableList(this.loginProviders);
    }

    /**
     * Get EFapsApplication for current thread.
     *
     * @return The current thread's Application
     */
    public static EFapsApplication get()
    {
        return (EFapsApplication) Application.get();
    }

    /**
     * Gets the max inactive interval.
     *
     * @return the max inactive interval
     */
    public static int getMaxInactiveInterval()
    {
        return EFapsApplication.MAXINACTIVEINTERVAL < 0 ? 0 : EFapsApplication.MAXINACTIVEINTERVAL;
    }

    /**
     * The Class presents the Strategy to authorize pages in this
     * WebApplication.
     */
    private class EFapsFormBasedAuthorizationStartegy
        implements IAuthorizationStrategy
    {

        /**
         * Wicket has got the possibility to check for specific actions like
         * render or enable if this given action is authorized. eFaps does not
         * use this check and returns always true.
         *
         * @see org.apache.wicket.authorization.IAuthorizationStrategy#isActionAuthorized(org.apache.wicket.Component,
         *      org.apache.wicket.authorization.Action)
         * @param _component Component to be checked
         * @param _action action to be checked
         * @return true
         */
        @Override
        public boolean isActionAuthorized(final Component _component,
                                          final Action _action)
        {
            return true;
        }

        /**
         * For all Pages it will be checked if a User is logged in or if the
         * Page implements the EFapsNoAuthendPageInterface, if non of both we
         * will redirect to the LoginPage.
         *
         * @param _componentClass class to be checked
         * @param <T> IRequestableComponent to be checked
         * @return true, if checks if is instantiation authorized
         */
        @Override
        public <T extends IRequestableComponent> boolean isInstantiationAuthorized(final Class<T> _componentClass)
        {
            boolean ret = true;
            if (WebPage.class.isAssignableFrom(_componentClass)) {
                if (((EFapsSession) Session.get()).isLogedIn() || EFapsNoAuthorizationNeededInterface.class
                                .isAssignableFrom(_componentClass)) {
                    ret = true;
                } else {
                    throw new RestartResponseAtInterceptPageException(LoginPage.class);
                }
            }
            return ret;
        }

        @Override
        public boolean isResourceAuthorized(final IResource _resource,
                                            final PageParameters _parameters)
        {
            return true;
        }
    }
}


/*
 * Copyright 2003 - 2016 The eFaps Team
 *
 * Licensed 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.efaps.ui.wicket.models.field.factories;

import java.util.List;

import org.apache.wicket.Component;
import org.apache.wicket.model.Model;
import org.efaps.admin.datamodel.ui.LinkWithRangesUI;
import org.efaps.api.ui.IOption;
import org.efaps.api.ui.UIType;
import org.efaps.ui.wicket.components.values.DropDownField;
import org.efaps.ui.wicket.models.field.AbstractUIField;
import org.efaps.ui.wicket.models.objects.DropDownOption;
import org.efaps.util.EFapsException;

/**
 * TODO comment!
 *
 * @author The eFaps Team
 */
// CHECKSTYLE:OFF
public final class LinkWithRangesUIFactory
    extends AbstractUIFactory
// CHECKSTYLE:ON
{

    /**
     * Factory Instance.
     */
    private static LinkWithRangesUIFactory FACTORY;

    /**
     * Singelton.
     */
    private LinkWithRangesUIFactory()
    {
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Component getEditable(final String _wicketId,
                                 final AbstractUIField _abstractUIField)
        throws EFapsException
    {
        Component ret = null;
        if (applies(_abstractUIField)) {
            ret = new DropDownField(_wicketId, Model.of(_abstractUIField), DropDownOption.getChoices(_abstractUIField
                            .getValue().getEditValue(_abstractUIField.getParent().getMode())));
        }
        return ret;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Component getHidden(final String _wicketId,
                               final AbstractUIField _abstractUIField)
        throws EFapsException
    {
        return null;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean applies(final AbstractUIField _uiField)
        throws EFapsException
    {
        return _uiField.getValue().getUIProvider() instanceof LinkWithRangesUI
                        && UIType.DEFAULT.equals(_uiField.getFieldConfiguration().getUIType());
    }

    /**
     * {@inheritDoc}
     */
    @SuppressWarnings("unchecked")
    @Override
    protected String getReadOnlyValue(final AbstractUIField _abstractUIField)
        throws EFapsException
    {
        String strValue = "";
        if (_abstractUIField.getValue().getDbValue() != null) {
            final Object valueObj = _abstractUIField.getValue().getReadOnlyValue(_abstractUIField.getParent()
                            .getMode());
            if (valueObj instanceof List) {
                final List<IOption> values = (List<IOption>) valueObj;
                if (values != null && !values.isEmpty()) {
                    if (values.size() == 1) {
                        strValue = values.get(0).getLabel();
                    } else {
                        for (final IOption option : values) {
                            if (option.isSelected()) {
                                strValue = option.getLabel();
                                break;
                            }
                        }
                    }
                }
            } else if (valueObj != null) {
                strValue = valueObj.toString();
            }
        }
        return strValue;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getKey()
    {
        return LinkWithRangesUIFactory.class.getName();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getPickListValue(final AbstractUIField _uiField)
        throws EFapsException
    {
        return getReadOnlyValue(_uiField);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Comparable<?> getCompareValue(final AbstractUIField _uiField)
        throws EFapsException
    {
        return getReadOnlyValue(_uiField);
    }

    /**
     * @return IComponentFactory instance
     */
    public static IComponentFactory get()
    {
        if (LinkWithRangesUIFactory.FACTORY == null) {
            LinkWithRangesUIFactory.FACTORY = new LinkWithRangesUIFactory();
        }
        return LinkWithRangesUIFactory.FACTORY;
    }
}


/*
 * Copyright 2015-2016 Hewlett-Packard Development Company, L.P.
 * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
 */

package com.hp.autonomy.hod.client.api.textindex.document;

import com.hp.autonomy.hod.client.converter.DoNotConvert;
import com.hp.autonomy.hod.client.util.MultiMap;
import lombok.Data;
import lombok.experimental.Accessors;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

@Data
@Accessors(chain = true)
public class AddToTextIndexRequestBuilder {

    /**
     * @param duplicateMode The duplicate mode of the document
     */
    private DuplicateMode duplicateMode;

    private List<String> referencePrefixes = new ArrayList<>();

    private List<Object> additionalMetadata = new ArrayList<>();

    /**
     * Adds values to the referencePrefixes parameter
     *
     * @param referencePrefix   The first index
     * @param referencePrefixes The remaining referencePrefixes
     * @return this
     */
    public AddToTextIndexRequestBuilder addReferencePrefixes(final String referencePrefix, final String... referencePrefixes) {
        this.referencePrefixes.add(referencePrefix);
        this.referencePrefixes.addAll(Arrays.asList(referencePrefixes));

        return this;
    }

    /**
     * Sets the value of the referencePrefixes parameter
     *
     * @param referencePrefixes The referencePrefixes to query
     * @return this
     */
    public AddToTextIndexRequestBuilder setReferencePrefixes(final List<String> referencePrefixes) {
        this.referencePrefixes = referencePrefixes;

        return this;
    }

    /**
     * Sets the value of the metadata parameter
     *
     * @param metadatum The first index
     * @param metadata  The remaining metadata
     * @return this
     */
    public AddToTextIndexRequestBuilder addAdditionalMetadata(final Object metadatum, final Object... metadata) {
        this.additionalMetadata.add(metadatum);
        this.additionalMetadata.addAll(Arrays.asList(metadata));

        return this;
    }

    /**
     * Sets the value of the metadata parameter
     *
     * @param metadata The metadata to query
     * @return this
     */
    public AddToTextIndexRequestBuilder setAdditionalMetadata(final List<Object> metadata) {
        this.additionalMetadata = metadata;

        return this;
    }

    /**
     * @return A map of query parameters suitable for use with {@link AddToTextIndexBackend}. get is NOT supported on
     * the resulting map
     */
    Map<String, Object> build() {
        final Map<String, Object> params = new MultiMap<>();

        params.put("duplicate_mode", duplicateMode);

        for (final String referencePrefix : referencePrefixes) {
            params.put("reference_prefix", referencePrefix);
        }

        for (final Object metadata : additionalMetadata) {
            params.put("additional_metadata", metadata);
        }

        return params;
    }

    /**
     * Enum representing all the possible values of the duplicate_mode parameter
     */
    @DoNotConvert
    public enum DuplicateMode {
        duplicate,
        replace
    }

}


/*
 * Copyright 2015-2016 Hewlett-Packard Development Company, L.P.
 * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
 */

package com.hp.autonomy.hod.client.api.queryprofile;

import com.hp.autonomy.hod.client.util.MultiMap;
import lombok.Data;
import lombok.experimental.Accessors;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;

/**
 * Helper class for building up optional parameters for the CreateQueryProfile API and UpdateQueryProfile API. Null parameters
 * or empty collections will not be sent to HP Haven OnDemand.
 */
@Data
@Accessors(chain = true)
public class QueryProfileRequestBuilder {
    /**
     * @param description Sets the value of the description parameter
     */
    private String description;

    /**
     * @param promotionsEnabled Sets the value of the promotions_enabled parameter
     */
    private Boolean promotionsEnabled;

    /**
     * @param promotionsIdentified Sets the value of the promotions_identified parameter
     */
    private Boolean promotionsIdentified;

    /**
     * @param synonymsEnabled Sets the value of the synonyms_enabled parameter
     */
    private Boolean synonymsEnabled;

    /**
     * @param blacklistsEnabled Sets the value of the blacklists_enabled parameter
     */
    private Boolean blacklistsEnabled;

    /**
     * @param promotionCategories Sets the value of the promotion_categories parameter
     */
    private Collection<String> promotionCategories = new ArrayList<>();

    /**
     * @param synonymCategories Sets the value of the synonym_categories parameter
     */
    private Collection<String> synonymCategories = new ArrayList<>();

    /**
     * @param blacklistCategories Sets the value of the blacklist_categories parameter
     */
    private Collection<String> blacklistCategories = new ArrayList<>();

    /**
     * Adds categories to the promotion_categories parameter
     *
     * @param category0  The first category to add
     * @param categories Additional categories to add
     * @return this
     */
    public QueryProfileRequestBuilder addPromotionCategories(final String category0, final String... categories) {
        promotionCategories.add(category0);
        promotionCategories.addAll(Arrays.asList(categories));
        return this;
    }

    /**
     * Adds categories to the synonym_categories parameter
     *
     * @param category0  The first category to add
     * @param categories Additional categories to add
     * @return this
     */
    public QueryProfileRequestBuilder addSynonymCategories(final String category0, final String... categories) {
        synonymCategories.add(category0);
        synonymCategories.addAll(Arrays.asList(categories));
        return this;
    }

    /**
     * Adds categories to the blacklist_categories parameter
     *
     * @param category0  The first category to add
     * @param categories Additional categories to add
     * @return this
     */
    public QueryProfileRequestBuilder addBlacklistCategories(final String category0, final String... categories) {
        blacklistCategories.add(category0);
        blacklistCategories.addAll(Arrays.asList(categories));
        return this;
    }

    MultiMap<String, Object> build() {
        final MultiMap<String, Object> params = new MultiMap<>();
        params.put("description", description);
        params.put("promotions_enabled", promotionsEnabled);
        params.put("promotions_identified", promotionsIdentified);
        params.put("synonyms_enabled", synonymsEnabled);
        params.put("blacklists_enabled", blacklistsEnabled);

        for (final String category : promotionCategories) {
            params.put("promotion_categories", category);
        }

        for (final String category : synonymCategories) {
            params.put("synonym_categories", category);
        }

        for (final String category : blacklistCategories) {
            params.put("blacklist_categories", category);
        }

        return params;
    }

}