nl.strohalm.cyclos.controls.elements.CreateElementAction.java Source code

Java tutorial

Introduction

Here is the source code for nl.strohalm.cyclos.controls.elements.CreateElementAction.java

Source

/*
This file is part of Cyclos (www.cyclos.org).
A project of the Social Trade Organisation (www.socialtrade.org).
    
Cyclos is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
    
Cyclos is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
    
You should have received a copy of the GNU General Public License
along with Cyclos; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
    
 */
package nl.strohalm.cyclos.controls.elements;

import nl.strohalm.cyclos.controls.ActionContext;
import nl.strohalm.cyclos.controls.BaseBindingForm;
import nl.strohalm.cyclos.controls.BaseFormAction;
import nl.strohalm.cyclos.entities.access.User;
import nl.strohalm.cyclos.entities.customization.fields.CustomField;
import nl.strohalm.cyclos.entities.customization.fields.CustomFieldValue;
import nl.strohalm.cyclos.entities.customization.fields.MemberCustomFieldValue;
import nl.strohalm.cyclos.entities.groups.Group;
import nl.strohalm.cyclos.entities.members.Element;
import nl.strohalm.cyclos.entities.members.Member;
import nl.strohalm.cyclos.entities.settings.AccessSettings;
import nl.strohalm.cyclos.entities.settings.LocalSettings;
import nl.strohalm.cyclos.services.elements.exceptions.NoInitialGroupException;
import nl.strohalm.cyclos.services.elements.exceptions.UsernameAlreadyInUseException;
import nl.strohalm.cyclos.utils.binding.BeanBinder;
import nl.strohalm.cyclos.utils.binding.BeanCollectionBinder;
import nl.strohalm.cyclos.utils.binding.DataBinder;
import nl.strohalm.cyclos.utils.binding.PropertyBinder;
import nl.strohalm.cyclos.utils.conversion.HtmlConverter;
import nl.strohalm.cyclos.utils.conversion.ReferenceConverter;
import nl.strohalm.cyclos.utils.validation.PasswordsDontMatchError;
import nl.strohalm.cyclos.utils.validation.ValidationException;

import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.struts.action.ActionForward;

/**
 * Action used to create an element
 * @author luis
 */
public abstract class CreateElementAction<E extends Element> extends BaseFormAction {

    @SuppressWarnings({ "unchecked", "rawtypes" })
    public static <E extends Element> DataBinder<E> getDataBinder(final LocalSettings localSettings,
            final AccessSettings accessSettings, final Class<E> elementClass, final Class userClass,
            final Class groupClass, final Class customField, final Class customFieldValue) {
        final BeanBinder<? extends CustomFieldValue> customValueBinder = BeanBinder.instance(customFieldValue);
        customValueBinder.registerBinder("field",
                PropertyBinder.instance(customField, "field", ReferenceConverter.instance(customField)));
        customValueBinder.registerBinder("value",
                PropertyBinder.instance(String.class, "value", HtmlConverter.instance()));
        if (MemberCustomFieldValue.class.isAssignableFrom(customFieldValue)) {
            customValueBinder.registerBinder("hidden", PropertyBinder.instance(Boolean.TYPE, "hidden"));
        }

        final BeanBinder<E> elementBinder = BeanBinder.instance(elementClass);
        elementBinder.registerBinder("name", PropertyBinder.instance(String.class, "name"));
        elementBinder.registerBinder("email", PropertyBinder.instance(String.class, "email"));
        if (Member.class.isAssignableFrom(elementClass)) {
            elementBinder.registerBinder("hideEmail", PropertyBinder.instance(Boolean.TYPE, "hideEmail"));
        }
        elementBinder.registerBinder("group",
                PropertyBinder.instance(groupClass, "group", ReferenceConverter.instance(groupClass)));
        elementBinder.registerBinder("customValues",
                BeanCollectionBinder.instance(customValueBinder, "customValues"));

        final BeanBinder<? extends User> userBinder = BeanBinder.instance(userClass, "user");
        if (!(Member.class.isAssignableFrom(elementClass) && accessSettings.isUsernameGenerated())) {
            userBinder.registerBinder("username", PropertyBinder.instance(String.class, "username"));
        }
        userBinder.registerBinder("password", PropertyBinder.instance(String.class, "password"));
        elementBinder.registerBinder("user", userBinder);

        return elementBinder;
    }

    protected DataBinder<? extends Element> dataBinder;

    public DataBinder<? extends Element> getDataBinder() {
        if (dataBinder == null) {
            dataBinder = getBaseBinder();
        }
        return dataBinder;
    }

    /**
     * Should be overriden to create the element
     */
    protected abstract ActionForward create(Element element, ActionContext context);

    protected DataBinder<? extends Element> getBaseBinder() {
        final LocalSettings localSettings = settingsService.getLocalSettings();
        final AccessSettings accessSettings = settingsService.getAccessSettings();
        return getDataBinder(localSettings, accessSettings, getElementClass(), getUserClass(), getGroupClass(),
                getCustomFieldClass(), getCustomFieldValueClass());
    }

    protected abstract <CF extends CustomField> Class<CF> getCustomFieldClass();

    protected abstract <CFV extends CustomFieldValue> Class<CFV> getCustomFieldValueClass();

    protected abstract Class<E> getElementClass();

    protected abstract <G extends Group> Class<G> getGroupClass();

    protected abstract <U extends User> Class<U> getUserClass();

    @Override
    protected ActionForward handleDisplay(final ActionContext context) throws Exception {
        try {
            prepareForm(context);
        } catch (final NoInitialGroupException e) {
            return context.sendError("createMember.error.noInitialGroup");
        }
        return context.getInputForward();
    }

    @Override
    protected ActionForward handleSubmit(final ActionContext context) throws Exception {
        final BaseBindingForm form = context.getForm();
        final Element element = getDataBinder().readFromString(form.getValues());
        element.setGroup(groupService.load(element.getGroup().getId()));
        ActionForward forward;
        try {
            forward = create(element, context);
        } catch (final NoInitialGroupException e) {
            return context.sendError("createMember.error.noInitialGroup");
        } catch (final UsernameAlreadyInUseException e) {
            return context.sendError("createMember.error.usernameAlreadyInUse", e.getUsername());
        }
        return forward == null ? context.getSuccessForward() : forward;
    }

    protected abstract void runValidation(final ActionContext context, final Element element);

    @Override
    protected void validateForm(final ActionContext context) {
        final CreateElementForm form = context.getForm();
        final Element element = getDataBinder().readFromString(form.getValues());

        ValidationException exc;
        try {
            runValidation(context, element);
            exc = new ValidationException();
        } catch (final ValidationException e) {
            exc = e;
        }

        String password;
        try {
            password = StringUtils.trimToNull(element.getUser().getPassword());
        } catch (final Exception e) {
            password = null;
        }

        final String confirmPassword = StringUtils.trimToNull(form.getConfirmPassword());
        if (password != null && (confirmPassword == null
                || !ObjectUtils.equals(confirmPassword, element.getUser().getPassword()))) {
            exc.addGeneralError(new PasswordsDontMatchError());
        }

        exc.throwIfHasErrors();
    }
}