Package org.apache.isis.viewer.html.task

Source Code of org.apache.isis.viewer.html.task.Task

/*
*  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.html.task;

import org.apache.isis.applib.profiles.Localization;
import org.apache.isis.core.commons.debug.DebugBuilder;
import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
import org.apache.isis.core.metamodel.facets.object.bounded.BoundedFacetUtils;
import org.apache.isis.core.metamodel.facets.object.parseable.InvalidEntryException;
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.progmodel.facets.value.password.PasswordValueFacet;
import org.apache.isis.core.runtime.system.context.IsisContext;
import org.apache.isis.viewer.html.component.Page;
import org.apache.isis.viewer.html.context.Context;
import org.apache.isis.viewer.html.request.Request;

/**
* Represents a task that the user is working through. Is used for both editing
* objects and setting up parameters for an action method.
*/
public abstract class Task {

    private static int nextID = 1;
    private int[] boundaries;
    private final String description;
    protected final String[] errors;
    protected String error;
    private final String[] entryText;
    protected final ObjectAdapter[] initialState;
    private final String name;
    protected final String[] names;
    protected final String[] descriptions;
    protected final boolean[] optional;
    protected final boolean[] readOnly;
    protected final int numberOfEntries;
    private int step;
    private final String targetId;
    protected final ObjectSpecification[] fieldSpecifications;
    protected final int[] noLines;
    protected final boolean[] wraps;
    protected final int[] maxLength;
    protected final int[] typicalLength;
    protected final int id = nextID++;

    public Task(final Context context, final String name, final String description, final ObjectAdapter target, final int noFields) {
        this.name = name;
        this.description = description;
        targetId = context.mapObject(target);

        initialState = new ObjectAdapter[noFields];
        names = new String[noFields];
        descriptions = new String[noFields];
        optional = new boolean[noFields];
        readOnly = new boolean[noFields];
        fieldSpecifications = new ObjectSpecification[noFields];

        numberOfEntries = noFields;
        entryText = new String[noFields];
        errors = new String[noFields];

        noLines = new int[noFields];
        wraps = new boolean[noFields];
        maxLength = new int[noFields];
        typicalLength = new int[noFields];
    }

    public void init(final Context context) {
        for (int i = 0; i < entryText.length; i++) {
            final ObjectAdapter obj = initialState[i];
            if (obj == null) {
                entryText[i] = "";
            } else if (obj.getSpecification().getFacet(PasswordValueFacet.class) != null) {
                final PasswordValueFacet facet = obj.getSpecification().getFacet(PasswordValueFacet.class);
                entryText[i] = facet.getEditText(obj);
            } else if (obj.getSpecification().isParseable()) {
                entryText[i] = obj.titleString();
            } else if (obj.getSpecification().isNotCollection()) {
                if (readOnly[i]) {
                    entryText[i] = (obj).titleString();
                } else {
                    entryText[i] = context.mapObject(obj);
                }
            } else if (obj.getSpecification().isParentedOrFreeCollection()) {
                entryText[i] = (obj).titleString();
            }
        }

        divyUpWork();
    }

    public abstract ObjectAdapter completeTask(Context context, Page page);

    private void copyForThisStep(final Object[] source, final Object[] destination) {
        for (int i = 0; i < noOfEntriesInThisStep(); i++) {
            destination[i] = source[firstEntryInThisStep() + i];
        }
    }

    private void copyForThisStep(final boolean[] source, final boolean[] destination) {
        for (int i = 0; i < noOfEntriesInThisStep(); i++) {
            destination[i] = source[firstEntryInThisStep() + i];
        }
    }

    private void copyForThisStep(final int[] source, final int[] destination) {
        for (int i = 0; i < noOfEntriesInThisStep(); i++) {
            destination[i] = source[firstEntryInThisStep() + i];
        }
    }

    public void checkInstances(final Context context, final ObjectAdapter[] objects) {
    }

    public void debug(final DebugBuilder debug) {
        debug.indent();
        debug.appendln("name", name);
        debug.appendln("number of steps ", numberOfSteps());
        debug.appendln("current step", step);
        debug.appendln("target", targetId);
        debug.appendln("steps (" + (boundaries.length - 1) + ")");
        debug.indent();
        for (int i = 0; i < boundaries.length - 1; i++) {
            debug.appendln("    " + (i + 1) + ". " + boundaries[i] + " - " + (boundaries[i + 1] - 1));
        }
        debug.unindent();
        debug.appendln("fields (" + names.length + ")");
        debug.indent();
        for (int i = 0; i < names.length; i++) {
            final String status = (readOnly[i] ? "R" : "-") + (optional[i] ? "O" : "M") + (errors[i] == null ? "-" : "E");
            debug.appendln("    " + i + "  " + names[i] + " (" + status + "):  " + fieldSpecifications[i].getFullIdentifier() + " -> " + entryText[i]);
        }
        debug.unindent();
        debug.unindent();
    }

    private void divyUpWork() {
        if (numberOfEntries == 0) {
            boundaries = new int[2];
        } else {
            final int[] b = new int[numberOfEntries + 2];
            int count = 0;
            b[count++] = 0;

            ObjectSpecification type = fieldSpecifications[0];
            boolean direct = simpleField(type, 0);

            for (int i = 1; i < numberOfEntries; i++) {
                type = fieldSpecifications[i];
                if (true || direct && (simpleField(type, i))) {
                    continue;
                }
                b[count++] = i;
                direct = simpleField(type, i);
            }
            b[count++] = numberOfEntries;
            boundaries = new int[count];
            System.arraycopy(b, 0, boundaries, 0, count);
        }
    }

    protected boolean simpleField(final ObjectSpecification specification, final int i) {
        return readOnly[i] || (specification.isNotCollection() && BoundedFacetUtils.isBoundedSet(specification));
    }

    private int firstEntryInThisStep() {
        return boundaries[step];
    }

    public String getDescription() {
        return description;
    }

    public String getError() {
        return error;
    }

    /**
     * Returns an array of errors, one for each element in the task.
     */
    public String[] getErrors() {
        final String[] array = new String[noOfEntriesInThisStep()];
        copyForThisStep(errors, array);
        return array;
    }

    public String[] getFieldDescriptions() {
        final String[] array = new String[noOfEntriesInThisStep()];
        copyForThisStep(descriptions, array);
        return array;
    }

    public String[] getEntryText() {
        final String[] array = new String[noOfEntriesInThisStep()];
        copyForThisStep(entryText, array);
        return array;
    }

    public String getName() {
        return name;
    }

    public String[] getNames() {
        final String[] array = new String[noOfEntriesInThisStep()];
        copyForThisStep(names, array);
        return array;
    }

    public ObjectAdapter[][] getOptions(final Context context) {
        return getOptions(context, firstEntryInThisStep(), noOfEntriesInThisStep());
    }

    protected ObjectAdapter[][] getOptions(final Context context, final int from, final int len) {
        return new ObjectAdapter[len][];
    }

    protected ObjectAdapter[] getEntries(final Context context) {
        final ObjectAdapter[] entries = new ObjectAdapter[entryText.length];
        for (int i = 0; i < entries.length; i++) {
            if (entryText == null || readOnly[i]) {
                continue;
            }
            final ObjectSpecification fieldSpecification = fieldSpecifications[i];
            if (fieldSpecification.isParseable()) {
                final ParseableFacet parser = fieldSpecification.getFacet(ParseableFacet.class);
                try {
                    Localization localization = IsisContext.getLocalization();
                    entries[i] = parser.parseTextEntry(initialState[i], entryText[i], localization);
                } catch (final InvalidEntryException e) {
                    errors[i] = e.getMessage();
                } catch (final TextEntryParseException e) {
                    errors[i] = e.getMessage();
                }
            } else if (fieldSpecification.isNotCollection() && entryText[i] != null) {
                if (entryText[i].equals("null")) {
                    entries[i] = null;
                } else {
                    entries[i] = context.getMappedObject(entryText[i]);
                }
            }
        }
        return entries;
    }

    public String getId() {
        return "" + id;
    }

    public boolean[] getOptional() {
        final boolean[] array = new boolean[noOfEntriesInThisStep()];
        copyForThisStep(optional, array);
        return array;
    }

    public int[] getNoLines() {
        final int[] array = new int[noOfEntriesInThisStep()];
        copyForThisStep(noLines, array);
        return array;
    }

    public boolean[] getWraps() {
        final boolean[] array = new boolean[noOfEntriesInThisStep()];
        copyForThisStep(wraps, array);
        return array;
    }

    public int[] getMaxLength() {
        final int[] array = new int[noOfEntriesInThisStep()];
        copyForThisStep(maxLength, array);
        return array;
    }

    public int[] getTypicalLength() {
        final int[] array = new int[noOfEntriesInThisStep()];
        copyForThisStep(typicalLength, array);
        return array;
    }

    public boolean[] getReadOnly() {
        final boolean[] array = new boolean[noOfEntriesInThisStep()];
        copyForThisStep(readOnly, array);
        return array;
    }

    public int getStep() {
        return step;
    }

    public ObjectAdapter getTarget(final Context context) {
        return context.getMappedObject(targetId);
    }

    public String[] getTrail() {
        final String[] trail = new String[boundaries.length - 1];
        for (int i = 0; i < trail.length; i++) {
            trail[i] = "step " + i;
        }
        return trail;
    }

    public ObjectSpecification[] getTypes() {
        final ObjectSpecification[] array = new ObjectSpecification[noOfEntriesInThisStep()];
        copyForThisStep(fieldSpecifications, array);
        return array;
    }

    public boolean isEditing() {
        return false;
    }

    public void nextStep() {
        step++;
    }

    private int noOfEntriesInThisStep() {
        return boundaries[step + 1] - boundaries[step];
    }

    public int numberOfSteps() {
        return boundaries.length - 1;
    }

    public void previousStep() {
        step--;
    }

    public void setFromFields(final Request request, final Context context) {
        int fldNo = 0;
        for (int i = boundaries[step]; i < boundaries[step + 1]; i++) {
            String textEntry = request.getFieldEntry(fldNo++);
            if (readOnly[i]) {
                continue;
            }
            final ObjectSpecification spec = fieldSpecifications[i];
            // deal with check boxes specially: expect 'true' if checked and no
            // entry if not checked, hence
            // need to set as 'false'
            if (spec.isOfType(IsisContext.getSpecificationLoader().loadSpecification(boolean.class)) || spec.isOfType(IsisContext.getSpecificationLoader().loadSpecification(Boolean.class))) {
                if (textEntry == null || !textEntry.equals("true")) {
                    textEntry = "false";
                }
            }
            entryText[i] = textEntry;
            try {
                errors[i] = null;
                setFromField(context, i, spec, textEntry);
                if (!optional[i] && (textEntry == null || textEntry.equals(""))) {
                    errors[i] = "Field required";
                }
            } catch (final InvalidEntryException e) {
                errors[i] = e.getMessage();
            } catch (final TextEntryParseException e) {
                errors[i] = e.getMessage();
            }
        }
    }

    private void setFromField(final Context context, final int i, final ObjectSpecification spec, final String textEntry) {
        if (spec.isParseable()) {
            if (textEntry == null) {
                return;
            }
            // REVIEW this block uses the existing adapter as it contains the
            // regex needed. This needs to
            // be reviewed in line with Dan's proposed changes to the reflector.
            final ObjectAdapter valueAdapter = initialState[i];
            final ParseableFacet parser = spec.getFacet(ParseableFacet.class);
            Localization localization = IsisContext.getLocalization();
            parser.parseTextEntry(valueAdapter, textEntry, localization);
            // REVIEW what do we do when an exception is thrown - a parse fails?
        }
    }

    public abstract void checkForValidity(Context context);

}
TOP

Related Classes of org.apache.isis.viewer.html.task.Task

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.