Package in.partake.controller.api.event

Source Code of in.partake.controller.api.event.ModifyTransaction

package in.partake.controller.api.event;

import in.partake.app.PartakeApp;
import in.partake.base.DateTime;
import in.partake.base.PartakeException;
import in.partake.base.TimeUtil;
import in.partake.base.Util;
import in.partake.controller.api.AbstractPartakeAPI;
import in.partake.controller.base.permission.EventEditPermission;
import in.partake.model.IPartakeDAOs;
import in.partake.model.UserEx;
import in.partake.model.access.Transaction;
import in.partake.model.dao.DAOException;
import in.partake.model.dao.PartakeConnection;
import in.partake.model.daofacade.EventDAOFacade;
import in.partake.model.daofacade.UserDAOFacade;
import in.partake.model.dto.Event;
import in.partake.model.dto.EventTicket;
import in.partake.model.dto.UserImage;
import in.partake.model.dto.auxiliary.EventCategory;
import in.partake.resource.UserErrorCode;
import in.partake.service.IEventSearchService;
import in.partake.view.util.Helper;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.codehaus.jackson.node.ArrayNode;
import org.codehaus.jackson.node.JsonNodeFactory;
import org.codehaus.jackson.node.ObjectNode;

import play.mvc.Result;

public class ModifyAPI extends AbstractPartakeAPI {

    public static Result post() throws DAOException, PartakeException {
        return new ModifyAPI().execute();
    }

    @Override
    protected Result doExecute() throws DAOException, PartakeException {
        UserEx user = ensureLogin();
        ensureValidSessionToken();
        String eventId = getValidEventIdParameter();
        Map<String, String[]> params = getFormParameters();

        ModifyTransaction transaction = new ModifyTransaction(user, eventId, params);
        transaction.execute();

        Event event = transaction.getEvent();
        List<EventTicket> tickets = transaction.getEventTickets();

        // If the event is already published, We update event search index.
        IEventSearchService searchService = PartakeApp.getEventSearchService();
        if (!event.isSearchable())
            searchService.remove(eventId);
        else if (searchService.hasIndexed(eventId))
            searchService.update(event, tickets);
        else
            searchService.create(event, tickets);

        ObjectNode obj = new ObjectNode(JsonNodeFactory.instance);
        obj.putAll(transaction.getJSONObject());
        return renderOK(obj);
    }
}

class ModifyTransaction extends Transaction<Void> {
    private UserEx user;
    private String eventId;
    private Map<String, String[]> params;

    private Event event;
    private List<EventTicket> tickets;
    private ObjectNode json;

    public ModifyTransaction(UserEx user, String eventId, Map<String, String[]> params) {
        this.user = user;
        this.eventId = eventId;
        this.params = params;

        // When event information is changed, you can add the editted value here to return to the client.
        // For example, you can filter script tag for event description, and so on.
        this.json = new ObjectNode(JsonNodeFactory.instance);
    }

    @Override
    protected Void doExecute(PartakeConnection con, IPartakeDAOs daos) throws DAOException, PartakeException {
        event = daos.getEventAccess().find(con, eventId);
        if (event == null)
            throw new PartakeException(UserErrorCode.INVALID_EVENT_ID);
        if (!EventEditPermission.check(event, user))
            throw new PartakeException(UserErrorCode.FORBIDDEN_EVENT_EDIT);

        event = new Event(event);
        updateEvent(con, daos);

        event.setModifiedAt(TimeUtil.getCurrentDateTime());
        EventDAOFacade.modify(con, daos, event);

        tickets = daos.getEventTicketAccess().findEventTicketsByEventId(con, eventId);

        return null;
    }

    private void updateEvent(PartakeConnection con, IPartakeDAOs daos) throws PartakeException, DAOException {
        if (params.containsKey("title")) {
            String title = getString("title");
            if (StringUtils.isBlank(title) || title.length() > 100)
                throw new PartakeException(UserErrorCode.INVALID_PARAMETERS, "title", "タイトルは 100 文字以下で必ず入力してください。");
            else
                event.setTitle(title);
        }

        if (params.containsKey("summary")) {
            String summary = getString("summary");
            if (summary != null && summary.length() > 100)
                throw new PartakeException(UserErrorCode.INVALID_PARAMETERS, "summary", "概要は 100 文字以下で入力してください。");
            else
                event.setSummary(summary);
        }

        if (params.containsKey("category")) {
            String category = getString("category");
            if (category == null || !EventCategory.isValidCategoryName(category))
                throw new PartakeException(UserErrorCode.INVALID_PARAMETERS, "category", "カテゴリーは正しいものを必ず入力してください。");
            else
                event.setCategory(category);
        }

        if (params.containsKey("beginDate")) {
            DateTime beginDate = getDateTime("beginDate");
            if (beginDate == null)
                throw new PartakeException(UserErrorCode.INVALID_PARAMETERS, "beginDate", "開始日時は必ず入力してください。");

            Calendar beginCalendar = TimeUtil.calendar(beginDate.toDate());
            if (beginCalendar.get(Calendar.YEAR) < 2000 || 2100 < beginCalendar.get(Calendar.YEAR))
                throw new PartakeException(UserErrorCode.INVALID_PARAMETERS, "beginDate", "開始日時の範囲が不正です。");
            else
                event.setBeginDate(beginDate);

            json.put("eventDuration", Helper.readableDuration(event.getBeginDate(), event.getEndDate()));
        }

        // TODO: What happend if beginDate is set after endDate is set and endDate <= beginDate. It should be an error.
        if (params.containsKey("endDate")) {
            String endDateStr = getString("endDate");
            if (StringUtils.isBlank(endDateStr))
                event.setEndDate(null);
            else {
                DateTime endDate = TimeUtil.parseForEvent(endDateStr);
                if (endDate == null)
                    throw new PartakeException(UserErrorCode.INVALID_PARAMETERS, "endDate", "終了日時が不正です。");
                else {
                    Calendar endCalendar = TimeUtil.calendar(endDate.toDate());
                    if (endCalendar.get(Calendar.YEAR) < 2000 || 2100 < endCalendar.get(Calendar.YEAR))
                        throw new PartakeException(UserErrorCode.INVALID_PARAMETERS, "endDate", "終了日時の範囲が不正です。");
                    else if (event.getBeginDate() != null && endDate.isBefore(event.getBeginDate()))
                        throw new PartakeException(UserErrorCode.INVALID_PARAMETERS, "endDate", "終了日時が開始日時より前になっています。");
                    else
                        event.setEndDate(endDate);
                }
            }
            json.put("eventDuration", Helper.readableDuration(event.getBeginDate(), event.getEndDate()));
        }

        if (params.containsKey("url")) {
            String urlStr = getString("url");
            if (StringUtils.isBlank(urlStr))
                event.setUrl(urlStr);
            else if (3000 < urlStr.length())
                throw new PartakeException(UserErrorCode.INVALID_PARAMETERS, "url", "URL が長すぎます。");
            else if (!urlStr.startsWith("http://") && !urlStr.startsWith("https://"))
                throw new PartakeException(UserErrorCode.INVALID_PARAMETERS, "url", "URL が不正です。");
            else {
                try {
                    new URL(urlStr)// Confirms URL is not malformed.
                    event.setUrl(urlStr);
                } catch (MalformedURLException e) {
                    throw new PartakeException(UserErrorCode.INVALID_PARAMETERS, "url", "URL が不正です。");
                }
            }
        }

        if (params.containsKey("place")) {
            String place = getString("place");
            if (place != null && 300 < place.length())
                throw new PartakeException(UserErrorCode.INVALID_PARAMETERS, "place", "場所が長すぎます");
            else
                event.setPlace(place);
        }

        if (params.containsKey("address")) {
            String address = getString("address");
            if (address != null && 300 < address.length())
                throw new PartakeException(UserErrorCode.INVALID_PARAMETERS, "address", "住所が長すぎます。");
            else
                event.setAddress(address);
        }

        if (params.containsKey("description")) {
            String description = getString("description");
            if (description != null && 1000000 < description.length())
                throw new PartakeException(UserErrorCode.INVALID_PARAMETERS, "description", "説明は 1000000 文字以下で入力してください。");
            else
                event.setDescription(description);
        }

        if (params.containsKey("hashTag")) {
            String hashTag = getString("hashTag");
            if (StringUtils.isBlank(hashTag))
                event.setHashTag(null);
            else if (100 < hashTag.length())
                throw new PartakeException(UserErrorCode.INVALID_PARAMETERS, "hashTag", "ハッシュタグは100文字以内で記述してください。");
            else if (!Util.isValidHashtag(hashTag))
                throw new PartakeException(UserErrorCode.INVALID_PARAMETERS, "hashTag", "ハッシュタグは # から始まる英数字や日本語が指定できます。記号は使えません。");
            else
                event.setHashTag(hashTag);
        }

        if (params.containsKey("passcode")) {
            String passcode = getString("passcode");
            if (StringUtils.isBlank(passcode))
                event.setPasscode(null);
            else if (20 < passcode.length())
                throw new PartakeException(UserErrorCode.INVALID_PARAMETERS, "passcode", "パスコードは20文字以下で記入してください。");
            else
                event.setPasscode(passcode);
        }

        if (params.containsKey("foreImageId")) {
            String foreImageId = getString("foreImageId");
            if (StringUtils.isBlank(foreImageId) || "null".equals(foreImageId))
                event.setForeImageId(null);
            else if (!Util.isUUID(foreImageId))
                throw new PartakeException(UserErrorCode.INVALID_PARAMETERS, "foreImageId", "画像IDが不正です。");
            else {
                // Check foreImageId is owned by the owner.
                UserImage image = daos.getImageAccess().find(con, foreImageId);
                if (image == null)
                    throw new PartakeException(UserErrorCode.INVALID_PARAMETERS, "foreImageId", "画像IDが不正です。");
                if (!user.getId().equals(image.getUserId()))
                    throw new PartakeException(UserErrorCode.INVALID_PARAMETERS, "foreImageId", "あなたが所持していない画像の ID が指定されています。");

                // OK.
                event.setForeImageId(foreImageId);
            }
        }

        if (params.containsKey("backImageId")) {
            String backImageId = getString("backImageId");
            if (StringUtils.isBlank(backImageId) || "null".equals(backImageId))
                event.setBackImageId(null);
            else if (!Util.isUUID(backImageId))
                throw new PartakeException(UserErrorCode.INVALID_PARAMETERS, "backImageId", "画像IDが不正です。");
            else {
                // Check foreImageId is owned by the owner.
                UserImage image = daos.getImageAccess().find(con, backImageId);
                if (image == null)
                    throw new PartakeException(UserErrorCode.INVALID_PARAMETERS, "backImageId", "画像IDが不正です。");
                if (!user.getId().equals(image.getUserId()))
                    throw new PartakeException(UserErrorCode.INVALID_PARAMETERS, "backImageId", "あなたが所持していない画像の ID が指定されています。");

                // OK.
                event.setBackImageId(backImageId);
            }
        }

        if (params.containsKey("relatedEventIds[]")) {
            Set<String> visitedIds = new HashSet<String>();
            String[] relatedEventIds = getStrings("relatedEventIds[]");

            List<String> eventIds = new ArrayList<String>();
            ArrayNode array = new ArrayNode(JsonNodeFactory.instance);
            for (String relatedEventId : relatedEventIds) {
                if (!Util.isUUID(relatedEventId))
                    continue;

                if (eventId.equals(relatedEventId))
                    continue;

                if (visitedIds.contains(relatedEventId))
                    continue;

                visitedIds.add(relatedEventId);

                Event relatedEvent = daos.getEventAccess().find(con, relatedEventId);
                if (relatedEvent == null)
                    continue;

                eventIds.add(relatedEventId);

                ObjectNode obj = new ObjectNode(JsonNodeFactory.instance);
                obj.put("id", relatedEvent.getId());
                obj.put("title", relatedEvent.getTitle());
                array.add(obj);
            }
            event.setRelatedEventIds(eventIds);

            // OK. We want to return event.id and event.title.
            json.put("relatedEvents", array);
        }

        if (params.containsKey("editorIds[]")) {
            ArrayNode array = new ArrayNode(JsonNodeFactory.instance);
            List<String> editorIds = new ArrayList<String>();
            Set<String> visitedIds = new HashSet<String>();
            for (String editorId : getStrings("editorIds[]")) {
                // Skips invalid users here.
                if (!Util.isUUID(editorId))
                    continue;

                if (visitedIds.contains(editorId))
                    continue;
                visitedIds.add(editorId);

                UserEx editor = UserDAOFacade.getUserEx(con, daos, editorId);
                if (editor == null)
                    continue;

                // OK.
                editorIds.add(editor.getId());
                array.add(editor.toSafeJSON());
            }

            event.setEditorIds(editorIds);
            json.put("editors", array);
        }
    }

    private String getString(String key) {
        Object obj = params.get(key);
        if (obj instanceof String)
            return (String) obj;
        else if (obj instanceof String[] && ((String[]) obj).length > 0)
            return ((String[]) obj)[0];
        else
            return null;
    }

    private String[] getStrings(String key) {
        Object obj = params.get(key);
        if (obj instanceof String)
            return new String[] { (String) obj };
        else if (obj instanceof String[])
            return (String[]) obj;
        else
            return null;
    }

    private DateTime getDateTime(String key) {
        String value = getString(key);
        if (value == null)
            return null;

        DateTime date = TimeUtil.parseForEvent(value);
        if (date != null)
            return date;

        return null;
    }

    public Event getEvent() {
        return event;
    }

    public List<EventTicket> getEventTickets() {
        return tickets;
    }

    public ObjectNode getJSONObject() {
        return json;
    }
}
TOP

Related Classes of in.partake.controller.api.event.ModifyTransaction

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.