ontopoly.components.FieldsEditorExistingPanel.java Source code

Java tutorial

Introduction

Here is the source code for ontopoly.components.FieldsEditorExistingPanel.java

Source

/*
 * #!
 * Ontopoly Editor
 * #-
 * Copyright (C) 2001 - 2013 The Ontopia Project
 * #-
 * Licensed 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 ontopoly.components;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import net.ontopia.utils.ObjectUtils;
import net.ontopia.utils.OntopiaRuntimeException;
import ontopoly.jquery.DraggableBehavior;
import ontopoly.jquery.DroppableBehavior;
import ontopoly.model.AssociationField;
import ontopoly.model.AssociationType;
import ontopoly.model.Cardinality;
import ontopoly.model.FieldAssignment;
import ontopoly.model.FieldDefinition;
import ontopoly.model.OccurrenceField;
import ontopoly.model.RoleField;
import ontopoly.model.Topic;
import ontopoly.model.TopicType;
import ontopoly.models.FieldAssignmentModel;
import ontopoly.models.FieldDefinitionModel;
import ontopoly.models.MutableLoadableDetachableModel;
import ontopoly.models.TopicTypeModel;
import ontopoly.pages.InstancePage;
import ontopoly.utils.TopicChoiceRenderer;

import org.apache.wicket.Component;
import org.apache.wicket.MarkupContainer;
import org.apache.wicket.PageParameters;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.behavior.SimpleAttributeModifier;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.ResourceModel;

public abstract class FieldsEditorExistingPanel extends Panel {

    private boolean readonly;

    public FieldsEditorExistingPanel(String id, final TopicTypeModel topicTypeModel,
            final FieldAssignmentModel fieldAssignmentModel, boolean readonly) {
        super(id);
        this.readonly = readonly;

        FieldAssignment fieldAssignment = fieldAssignmentModel.getFieldAssignment();

        WebMarkupContainer container = new WebMarkupContainer("field", fieldAssignmentModel);
        add(container);

        OntopolyImage icon = new OntopolyImage("icon", "dnd.gif", new ResourceModel("icon.dnd.reorder"));
        icon.setVisible(!readonly);
        container.add(icon);

        FieldDefinition fieldDefinition = fieldAssignment.getFieldDefinition();
        final FieldDefinitionModel fieldDefinitionModel = new FieldDefinitionModel(fieldDefinition);

        container.add(new FieldDefinitionLabel("fieldLabel", fieldDefinitionModel) {
            @Override
            protected boolean isFieldDefinitionLinkEnabled(Topic topic) {
                return true;
            }

            @Override
            protected boolean isOntologyTypeLinkEnabled(Topic topic) {
                return true;
            }
        });

        Component fieldType = getFieldType("valueType",
                fieldAssignmentModel.getFieldAssignment().getFieldDefinition());
        fieldType.setRenderBodyOnly(true);
        container.add(fieldType);

        Component cardinalityComponent = getCardinality("cardinality", fieldAssignmentModel);
        cardinalityComponent.setEnabled(!readonly);
        container.add(cardinalityComponent);

        // drag and drop
        if (!readonly) {
            String dndId = "fields_" + topicTypeModel.getTopicType().getId();
            container.add(new DraggableBehavior(dndId));
            container.add(new DroppableBehavior(dndId) {
                @Override
                protected MarkupContainer getDropContainer() {
                    return FieldsEditorExistingPanel.this.getParent().getParent();
                }

                @Override
                protected void onDrop(Component component, AjaxRequestTarget target) {
                    FieldAssignmentModel fam_dg = (FieldAssignmentModel) component.getDefaultModel();
                    FieldAssignmentModel fam_do = (FieldAssignmentModel) getComponent().getDefaultModel();
                    FieldAssignment fa_dg = fam_dg.getFieldAssignment();
                    FieldAssignment fa_do = fam_do.getFieldAssignment();
                    fa_do.moveAfter(fa_dg);
                    FieldsEditorExistingPanel.this.onMoveAfter(fam_dg, fam_do, target);
                }
            });
        }

        TopicType topicType = topicTypeModel.getTopicType();
        TopicType declaredTopicType = fieldAssignmentModel.getFieldAssignment().getDeclaredTopicType();

        if (ObjectUtils.equals(topicType, declaredTopicType)) {
            OntopolyImageLink button = new OntopolyImageLink("button", "remove-value.gif",
                    new ResourceModel("icon.remove.field")) {
                @Override
                public void onClick(AjaxRequestTarget target) {
                    FieldsEditorExistingPanel.this.onRemove(fieldAssignmentModel, target);
                }

                @Override
                public boolean isVisible() {
                    return !FieldsEditorExistingPanel.this.readonly;
                    //! || (fieldDefinitionModel.getFieldDefinition().isSystemTopic() && ((OntopolySession)Session.get()).isAdministrationEnabled());
                }
            };
            container.add(button);
        } else {
            OntopolyImageLink button = new OntopolyImageLink("button", "goto.gif",
                    new ResourceModel("icon.goto.assigning-type")) {
                @Override
                public void onClick(AjaxRequestTarget target) {
                    TopicType declaredTopicType = fieldAssignmentModel.getFieldAssignment().getDeclaredTopicType();
                    Map<String, String> pageParametersMap = new HashMap<String, String>(3);
                    pageParametersMap.put("topicMapId", declaredTopicType.getTopicMap().getId());
                    pageParametersMap.put("topicId", declaredTopicType.getId());
                    pageParametersMap.put("ontology", "true");
                    setResponsePage(InstancePage.class, new PageParameters(pageParametersMap));
                }
            };
            container.add(button);
        }
    }

    protected abstract void onMoveAfter(FieldAssignmentModel fam_dg, FieldAssignmentModel fam_do,
            AjaxRequestTarget target);

    protected abstract void onRemove(FieldAssignmentModel fam, AjaxRequestTarget target);

    static Component getFieldType(String id, FieldDefinition fieldDefinition) {

        switch (fieldDefinition.getFieldType()) {
        case FieldDefinition.FIELD_TYPE_ROLE: {
            TopicType tt = null;
            RoleField rf = (RoleField) fieldDefinition;
            AssociationField afield = rf.getAssociationField();
            List<RoleField> fields = afield.getFieldsForRoles();
            int numberOfRoles = fields.size();
            String fieldTypeAsString = "";
            if (numberOfRoles == 1) { // unary
                return new Label(id, new ResourceModel("FieldsEditorExistingPanel.valuetype.unary"));
            } else if (numberOfRoles == 2) { // binary
                AssociationType at = rf.getAssociationType();
                if (at.isSymmetric()) { // symmetric
                    Collection<TopicType> allowedValueTypes = rf.getDeclaredPlayerTypes();
                    if (allowedValueTypes.size() == 1) { // only one allowed player
                        Iterator<TopicType> it = allowedValueTypes.iterator();
                        // It's only one element in the list
                        while (it.hasNext()) {
                            tt = it.next();
                            fieldTypeAsString = tt.getName();
                        }
                    } else { // more than one allowed player
                        return new Label(id, new ResourceModel("FieldsEditorExistingPanel.valuetype.many"))
                                .add(new SimpleAttributeModifier("title", getAllowedPlayerNames(rf)))
                                .add(new SimpleAttributeModifier("class", "italic"));
                    }
                } else { // binary
                    Iterator<RoleField> it = fields.iterator();
                    while (it.hasNext()) {
                        RoleField rf2 = it.next();
                        if (!rf.equals(rf2)) { // the other association field
                            Collection<TopicType> allowedValueTypes = rf2.getDeclaredPlayerTypes();
                            if (allowedValueTypes.size() == 1) { // only one allowed player
                                Iterator<TopicType> it2 = allowedValueTypes.iterator();
                                // It's only one element in the list
                                while (it2.hasNext()) {
                                    tt = (TopicType) it2.next();
                                    fieldTypeAsString = tt.getName();
                                }
                            } else { // more than one allowed player  
                                return new Label(id, new ResourceModel("FieldsEditorExistingPanel.valuetype.many"))
                                        .add(new SimpleAttributeModifier("title", getAllowedPlayerNames(rf)))
                                        .add(new SimpleAttributeModifier("class", "italic"));
                            }
                        }
                    }
                }
            } else if (numberOfRoles > 2) { // n-ary
                return new Label(id, new ResourceModel("FieldsEditorExistingPanel.valuetype.many"))
                        .add(new SimpleAttributeModifier("title", getAllowedPlayerNames(rf)))
                        .add(new SimpleAttributeModifier("class", "italic"));
            }

            // Create link if the association field is for a binary association
            // with only one topic type on the other side of the association.
            PageParameters params = new PageParameters();
            params.put("topicMapId", fieldDefinition.getTopicMap().getId());
            params.put("ontology", "true");
            if (tt != null)
                params.put("topicId", tt.getId());

            return new OntopolyBookmarkablePageLink(id, InstancePage.class, params, fieldTypeAsString);
        }
        case FieldDefinition.FIELD_TYPE_IDENTITY: {
            return new Label(id, new ResourceModel("FieldsEditorExistingPanel.valuetype.uri"));
        }
        case FieldDefinition.FIELD_TYPE_NAME: {
            return new Label(id, new ResourceModel("FieldsEditorExistingPanel.valuetype.name"));
        }
        case FieldDefinition.FIELD_TYPE_OCCURRENCE: {
            return new Label(id, ((OccurrenceField) fieldDefinition).getDataType().getName());
        }
        case FieldDefinition.FIELD_TYPE_QUERY: {
            return new Label(id, new Model<String>("Query"));
        }
        default:
            throw new OntopiaRuntimeException("Unknown field definition: " + fieldDefinition.getFieldType());
        }
    }

    private static String getAllowedPlayerNames(RoleField rf) {
        Set<String> topicTypeNames = new TreeSet<String>();

        AssociationField afield = rf.getAssociationField();
        Iterator<RoleField> it = afield.getFieldsForRoles().iterator();
        while (it.hasNext()) {
            RoleField af2 = (RoleField) it.next();
            if (!rf.equals(af2)) { // one of the other association fields
                Iterator<TopicType> it2 = af2.getDeclaredPlayerTypes().iterator();
                while (it2.hasNext()) {
                    topicTypeNames.add(((TopicType) it2.next()).getName());
                }
            }
        }
        return topicTypeNames.toString();
    }

    private static Component getCardinality(String id, final FieldAssignmentModel fam) {
        LoadableDetachableModel<List<Cardinality>> cardinalityChoicesModel = new LoadableDetachableModel<List<Cardinality>>() {
            @Override
            protected List<Cardinality> load() {
                return Cardinality.getCardinalityTypes(fam.getFieldAssignment().getFieldDefinition().getTopicMap());
            }
        };
        final IModel<Cardinality> cardModel = new MutableLoadableDetachableModel<Cardinality>() {
            @Override
            protected Cardinality load() {
                return fam.getFieldAssignment().getCardinality();
            }

            @Override
            public void setObject(Cardinality card) {
                fam.getFieldAssignment().getFieldDefinition().setCardinality(card);
                super.setObject(card);
            }
        };
        AjaxOntopolyDropDownChoice<Cardinality> choice = new AjaxOntopolyDropDownChoice<Cardinality>(id, cardModel,
                cardinalityChoicesModel, new TopicChoiceRenderer<Cardinality>());
        return choice;
    }
}