com.opensymphony.able.action.DefaultCrudActionBean.java Source code

Java tutorial

Introduction

Here is the source code for com.opensymphony.able.action.DefaultCrudActionBean.java

Source

/**
 *
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.opensymphony.able.action;

import com.opensymphony.able.annotations.Partial;
import com.opensymphony.able.filter.TransactionOutcome;
import com.opensymphony.able.introspect.EntityInfo;
import com.opensymphony.able.introspect.PropertyInfo;
import com.opensymphony.able.service.CrudService;
import com.opensymphony.able.service.JpaCrudService;
import com.opensymphony.able.stripes.DefaultResolution;
import com.opensymphony.able.stripes.GenerateResolution;
import com.opensymphony.able.util.EnumHelper;
import static com.opensymphony.able.util.StringHelper.notBlank;
import com.opensymphony.able.xml.JaxbResolution;
import com.opensymphony.able.xml.JaxbTemplate;
import net.sourceforge.stripes.action.ActionBean;
import net.sourceforge.stripes.action.DefaultHandler;
import net.sourceforge.stripes.action.DontValidate;
import net.sourceforge.stripes.action.RedirectResolution;
import net.sourceforge.stripes.action.Resolution;
import net.sourceforge.stripes.integration.spring.SpringBean;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.AbstractMap;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * A default {@link ActionBean} implementation that uses a @{link CrudService}
 *
 * @version $Revision$
 */
public class DefaultCrudActionBean<E> extends EntityActionBeanSupport<E> {
    private static final Log log = LogFactory.getLog(DefaultCrudActionBean.class);

    private CrudService<E> service;
    @SpringBean
    private Validator validator;
    @SpringBean
    private QueryStrategy queryStrategy;

    private E entity;
    private String query;

    public DefaultCrudActionBean() {
    }

    public DefaultCrudActionBean(Class<E> entityClass) {
        super(entityClass);
    }

    public DefaultCrudActionBean(CrudService<E> service) {
        this(service.getEntityClass());
    }

    public DefaultCrudActionBean(CrudService<E> service, QueryStrategy queryStrategy, Validator validator) {
        this(service);
        this.queryStrategy = queryStrategy;
        this.validator = validator;
    }

    // Actions
    // -------------------------------------------------------------------------

    /**
     * Generates a tabular view
     */
    @DontValidate
    @DefaultHandler
    public Resolution list() {
        return new DefaultResolution(getClass(), getContext(), "/WEB-INF/jsp/generic/list.jsp");
    }

    @Partial
    @DontValidate
    public Resolution generateList() {
        return new GenerateResolution(getClass(), getContext());
    }

    /**
     * Views a single entity in a read only form
     */
    public Resolution view() {
        return new DefaultResolution(getClass(), getContext(), "/WEB-INF/jsp/generic/view.jsp?entity=");
    }

    @Partial
    @DontValidate
    public Resolution generateView() {
        return new GenerateResolution(getClass(), getContext());
    }

    /**
     * Views the edit form
     */
    public Resolution edit() {
        return new DefaultResolution(getClass(), getContext(), "/WEB-INF/jsp/generic/edit.jsp?entity=");
    }

    @Partial
    @DontValidate
    public Resolution generateEdit() {
        return new GenerateResolution(getClass(), getContext());
    }

    /**
     * Deletes the current entity
     */
    @DontValidate
    public Resolution delete() {
        E e = getEntity();
        if (e != null) {
            Object idValue = getEntityInfo().getIdValue(e);
            if (idValue != null) {
                getService().delete(e);
                TransactionOutcome.shouldCommit();
            }
        }
        return new RedirectResolution(getActionUri());
    }

    /**
     * Saves an edit form
     */
    public Resolution save() {
        validate();
        if (getContext().getValidationErrors().isEmpty()) {
            E e = getEntity();
            if (e != null) {
                Object idValue = getEntityInfo().getIdValue(e);
                if (idValue == null) {
                    getService().insert(e);
                } else {
                    getService().update(e);
                }
                TransactionOutcome.shouldCommit();
                return new RedirectResolution(getActionUri());
            }
        }
        return getContext().getSourcePageResolution();
    }

    /**
     * Cancels any edits
     */
    @DontValidate
    public Resolution cancel() {
        TransactionOutcome.shouldRollback();

        // TODO
        // getContext().addMsg( Messages.cancelled( "Manufacturer" ) );

        return new RedirectResolution(getActionUri());
    }

    /**
     * Performs a search
     */
    public Resolution search() {
        return getContext().getSourcePageResolution();
    }

    /**
     * A RESTful view as a blob of XML
     */
    public Resolution xmlView() {
        return new JaxbResolution(new JaxbTemplate(entityClass), getEntity());
    }

    /**
     * The current entity
     */
    public E getEntity() {
        if (entity == null) {
            // lets lazily create an instance so we pre-populate the
            // create new edit form
            try {
                entity = getService().newInstance();
            } catch (Exception e) {
                throw new RuntimeException(
                        "Failed to create a new instance of: " + getEntityClass() + ". Reason: " + e, e);
            }
        }
        return entity;
    }

    public void setEntity(E entity) {
        this.entity = entity;
    }

    /**
     * Returns the primary key of the entity
     */
    public Object getId() {
        return getEntityInfo().getIdValue(getEntity());
    }

    @SuppressWarnings("unchecked")
    public List<E> getAllEntities() {
        String text = getQuery();
        if (notBlank(text)) {
            if (queryStrategy == null) {
                throw new IllegalArgumentException("No QueryStrategy was injected!");
            }
            List answer = queryStrategy.execute(entityClass, text);
            log.info("Query with: " + text + " found: " + answer);
            return answer;
        }
        return getService().findAll();
    }

    public Map<String, Object> getAllValues() {
        return new AbstractMap<String, Object>() {

            @Override
            public Object get(Object propertyName) {
                return getAllValuesForProperty((String) propertyName);
            }

            @Override
            public Set<Entry<String, Object>> entrySet() {
                return Collections.EMPTY_SET;
            }
        };
    }

    /**
     * @return the text query being used
     */
    public String getQuery() {
        return query;
    }

    public void setQuery(String query) {
        this.query = query;
    }

    public QueryStrategy getQueryStrategy() {
        return queryStrategy;
    }

    public CrudService<E> getService() {
        if (service == null) {
            service = createService();
        }
        return service;
    }

    // Implementation methods
    // -------------------------------------------------------------------------

    /**
     * Performs any custom validation
     */
    protected void validate() {
        if (validator != null) {
            validator.validate(getContext(), "entity.", getEntity());
        }
    }

    /**
     * Returns a collection of values for the given property name of this entity.
     * This method is used so we can render pick lists of values to be chosen for related values
     */
    protected Object getAllValuesForProperty(String propertyName) {
        PropertyInfo property = getEntityInfo().getProperty(propertyName);
        if (property == null) {
            throw new IllegalArgumentException("Entity " + getEntityInfo().getEntityName()
                    + " does not have a property called: " + propertyName);
        }
        EntityInfo propertyTypeInfo = property.getPropertyEntityInfo();
        if (propertyTypeInfo.isPersistent()) {
            CrudService<E> s = getService();
            if (s instanceof JpaCrudService) {
                JpaCrudService jpaService = (JpaCrudService) s;
                return jpaService.getJpaTemplate().find(propertyTypeInfo.getFindAllQuery());
            }
        } else {
            Class propertyType = propertyTypeInfo.getEntityClass();
            if (Enum.class.isAssignableFrom(propertyType)) {
                try {
                    return Arrays.asList(EnumHelper.getEnumValues(propertyType));
                } catch (Exception e) {
                    log.error("Attempting to find all enum types of : " + propertyType + ". Caught: " + e, e);
                }
            }
        }
        log.warn("No such property: " + propertyName + " for entity: " + entityInfo.getEntityName());
        return Collections.EMPTY_LIST;
    }

    protected CrudService<E> createService() {
        throw new IllegalArgumentException("No service property has been configured!");
    }

    protected EntityInfo createEntityInfo() {
        return EntityInfo.newInstance(getService().getEntityClass());
    }

}