Package org.apache.isis.viewer.scimpi.dispatcher.edit

Source Code of org.apache.isis.viewer.scimpi.dispatcher.edit.EditAction

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

package org.apache.isis.viewer.scimpi.dispatcher.edit;

import java.io.IOException;
import java.util.List;

import org.apache.isis.core.commons.authentication.AnonymousSession;
import org.apache.isis.core.commons.authentication.AuthenticationSession;
import org.apache.isis.core.commons.debug.DebugBuilder;
import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
import org.apache.isis.core.metamodel.adapter.version.Version;
import org.apache.isis.core.metamodel.consent.Consent;
import org.apache.isis.core.metamodel.consent.Veto;
import org.apache.isis.core.metamodel.facets.object.parseable.ParseableFacet;
import org.apache.isis.core.metamodel.facets.object.parseable.TextEntryParseException;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
import org.apache.isis.core.metamodel.spec.feature.ObjectAssociationFilters;
import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
import org.apache.isis.runtimes.dflt.runtime.system.context.IsisContext;
import org.apache.isis.runtimes.dflt.runtime.system.transaction.MessageBroker;
import org.apache.isis.viewer.scimpi.dispatcher.Action;
import org.apache.isis.viewer.scimpi.dispatcher.Dispatcher;
import org.apache.isis.viewer.scimpi.dispatcher.NotLoggedInException;
import org.apache.isis.viewer.scimpi.dispatcher.context.RequestContext;
import org.apache.isis.viewer.scimpi.dispatcher.context.RequestContext.Scope;

public class EditAction implements Action {
    public static final String ACTION = "edit";

    @Override
    public String getName() {
        return ACTION;
    }

    @Override
    public void process(final RequestContext context) throws IOException {
        AuthenticationSession session = context.getSession();
        if (session == null) {
            session = new AnonymousSession();
        }

        try {
            final String objectId = context.getParameter("_" + OBJECT);
            final String version = context.getParameter("_" + VERSION);
            final String formId = context.getParameter("_" + FORM_ID);
            String resultName = context.getParameter("_" + RESULT_NAME);
            resultName = resultName == null ? RequestContext.RESULT : resultName;
            final String override = context.getParameter("_" + RESULT_OVERRIDE);
            String message = context.getParameter("_" + MESSAGE);

            final ObjectAdapter adapter = context.getMappedObject(objectId);

            final List<ObjectAssociation> fields = adapter.getSpecification().getAssociations(ObjectAssociationFilters.dynamicallyVisible(session, adapter));

            for (final ObjectAssociation objectAssociation : fields) {
                if (objectAssociation.isVisible(session, adapter).isVetoed()) {
                    throw new NotLoggedInException();
                }
            }

            final FormState entryState = validateObject(context, adapter, fields);
            final Version adapterVersion = adapter.getVersion();
            final Version formVersion = context.getVersion(version);
            if (formVersion != null && adapterVersion.different(formVersion)) {

                IsisContext.getMessageBroker().addMessage("The " + adapter.getSpecification().getSingularName() + " was edited " + "by another user (" + adapterVersion.getUser() + "). Please  make your changes based on their changes.");

                final String view = context.getParameter("_" + ERROR);
                context.setRequestPath(view, Dispatcher.EDIT);

                entryState.setForm(formId);
                context.addVariable(ENTRY_FIELDS, entryState, Scope.REQUEST);
                context.addVariable(resultName, objectId, Scope.REQUEST);
                if (override != null) {
                    context.addVariable(resultName, override, Scope.REQUEST);
                }

            } else if (entryState.isValid()) {
                changeObject(context, adapter, entryState, fields);

                if (adapter.isTransient()) {
                    IsisContext.getPersistenceSession().makePersistent(adapter);
                    context.unmapObject(adapter, Scope.REQUEST);
                }

                String view = context.getParameter("_" + VIEW);

                final String id = context.mapObject(adapter, Scope.REQUEST);
                context.addVariable(resultName, id, Scope.REQUEST);
                if (override != null) {
                    context.addVariable(resultName, override, Scope.REQUEST);
                }

                final int questionMark = view == null ? -1 : view.indexOf("?");
                if (questionMark > -1) {
                    final String params = view.substring(questionMark + 1);
                    final int equals = params.indexOf("=");
                    context.addVariable(params.substring(0, equals), params.substring(equals + 1), Scope.REQUEST);
                    view = view.substring(0, questionMark);
                }
                context.setRequestPath(view);
                if (message == null) {
                    message = "Saved changes to " + adapter.getSpecification().getSingularName();
                } else if (message.equals("")) {
                    message = null;
                }
                if (message != null) {
                    final MessageBroker messageBroker = IsisContext.getMessageBroker();
                    messageBroker.addMessage(message);
                }

            } else {
                final String view = context.getParameter("_" + ERROR);
                context.setRequestPath(view, Dispatcher.EDIT);

                entryState.setForm(formId);
                context.addVariable(ENTRY_FIELDS, entryState, Scope.REQUEST);
                context.addVariable(resultName, objectId, Scope.REQUEST);
                if (override != null) {
                    context.addVariable(resultName, override, Scope.REQUEST);
                }

                final MessageBroker messageBroker = IsisContext.getMessageBroker();
                messageBroker.addWarning(entryState.getError());
            }

        } catch (final RuntimeException e) {
            IsisContext.getMessageBroker().getMessages();
            IsisContext.getMessageBroker().getWarnings();
            IsisContext.getUpdateNotifier().clear();
            IsisContext.getUpdateNotifier().clear();
            throw e;
        }
    }

    private FormState validateObject(final RequestContext context, final ObjectAdapter object, final List<ObjectAssociation> fields) {
        final FormState formState = new FormState();
        for (int i = 0; i < fields.size(); i++) {
            final ObjectAssociation field = fields.get(i);
            final String fieldId = field.getId();
            String newEntry = context.getParameter(fieldId);
            if (fields.get(i).isOneToManyAssociation()) {
                continue;
            }
            if (fields.get(i).isVisible(IsisContext.getAuthenticationSession(), object).isVetoed()) {
                continue;
            }
            if (field.isUsable(IsisContext.getAuthenticationSession(), object).isVetoed()) {
                continue;
            }

            if (newEntry != null && newEntry.equals("-OTHER-")) {
                newEntry = context.getParameter(fieldId + "-other");
            }

            if (newEntry == null) {
                // TODO duplicated in EditObject; line 97
                final ObjectSpecification spec = field.getSpecification();
                if (spec.isOfType(IsisContext.getSpecificationLoader().loadSpecification(boolean.class)) || spec.isOfType(IsisContext.getSpecificationLoader().loadSpecification(Boolean.class))) {
                    newEntry = FALSE;
                } else {
                    continue;
                }
            }
            final FieldEditState fieldState = formState.createField(fieldId, newEntry);

            Consent consent = null;
            if (field.isMandatory() && (newEntry.equals("") || newEntry.equals("NULL"))) {
                consent = new Veto(field.getName() + " required");
                formState.setError("Not all fields have been set");
            } else if (field.getSpecification().containsFacet(ParseableFacet.class)) {
                try {
                    final ParseableFacet facet = field.getSpecification().getFacet(ParseableFacet.class);
                    final ObjectAdapter originalValue = field.get(object);
                    final ObjectAdapter newValue = facet.parseTextEntry(originalValue, newEntry);
                    consent = ((OneToOneAssociation) field).isAssociationValid(object, newValue);
                    fieldState.setValue(newValue);
                } catch (final TextEntryParseException e) {
                    consent = new Veto(e.getMessage());
                    // formState.setError("Not all fields have been entered correctly");
                }

            } else {
                final ObjectAdapter associate = newEntry.equals("null") ? null : context.getMappedObject(newEntry);
                if (associate != null) {
                    IsisContext.getPersistenceSession().resolveImmediately(associate);
                }
                consent = ((OneToOneAssociation) field).isAssociationValid(object, associate);
                fieldState.setValue(associate);

            }
            if (consent.isVetoed()) {
                fieldState.setError(consent.getReason());
                formState.setError("Not all fields have been entered correctly");
            }
        }

        // TODO check the state of the complete object.
        return formState;
    }

    private void changeObject(final RequestContext context, final ObjectAdapter object, final FormState editState, final List<ObjectAssociation> fields) {
        for (int i = 0; i < fields.size(); i++) {
            final FieldEditState field = editState.getField(fields.get(i).getId());
            if (field == null) {
                continue;
            }
            final String newEntry = field.getEntry();
            final ObjectAdapter originalValue = fields.get(i).get(object);
            final boolean isVisible = fields.get(i).isVisible(IsisContext.getAuthenticationSession(), object).isAllowed();
            final boolean isUsable = fields.get(i).isUsable(IsisContext.getAuthenticationSession(), object).isAllowed();
            final boolean bothEmpty = originalValue == null && newEntry.equals("");
            final boolean bothSame = newEntry.equals(originalValue == null ? "" : originalValue.titleString());
            if ((!isVisible || !isUsable) || bothEmpty || bothSame) {
                if (fields.get(i).getSpecification().getFacet(ParseableFacet.class) == null) {
                    // REVIEW restores object to loader
                    context.getMappedObject(newEntry);
                }
                continue;
            }

            if (fields.get(i).getSpecification().containsFacet(ParseableFacet.class)) {
                final ParseableFacet facet = fields.get(i).getSpecification().getFacet(ParseableFacet.class);
                final ObjectAdapter newValue = facet.parseTextEntry(originalValue, newEntry);
                ((OneToOneAssociation) fields.get(i)).set(object, newValue);
            } else {
                ((OneToOneAssociation) fields.get(i)).set(object, field.getValue());
            }
        }
    }

    @Override
    public void init() {
    }

    @Override
    public void debug(final DebugBuilder debug) {
    }
}
TOP

Related Classes of org.apache.isis.viewer.scimpi.dispatcher.edit.EditAction

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.