/* * #! * 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.Comparator; import java.util.List; import net.ontopia.utils.ObjectUtils; import ontopoly.model.FieldAssignment; import ontopoly.model.FieldInstance; import ontopoly.model.RoleField; import ontopoly.model.Topic; import ontopoly.models.FieldDefinitionModel; import ontopoly.models.FieldInstanceModel; import ontopoly.models.FieldValueModel; import ontopoly.models.FieldValuesModel; import ontopoly.models.FieldsViewModel; import ontopoly.models.RoleFieldModel; import ontopoly.models.TopicModel; import ontopoly.pages.AbstractOntopolyPage; import ontopoly.utils.RoleFieldsValueComparator; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.list.ListItem; import org.apache.wicket.markup.html.list.ListView; import org.apache.wicket.markup.html.panel.FeedbackPanel; import org.apache.wicket.model.IModel; import org.apache.wicket.model.ResourceModel; public class FieldInstanceAssociationNaryPanel extends AbstractFieldInstancePanel { public FieldInstanceAssociationNaryPanel(String id, final FieldInstanceModel fieldInstanceModel, final FieldsViewModel fieldsViewModel, final boolean readonly, final boolean traversable, final int arity) { super(id, fieldInstanceModel); FieldInstance fieldInstance = fieldInstanceModel.getFieldInstance(); FieldAssignment fieldAssignment = fieldInstance.getFieldAssignment(); RoleField roleField = (RoleField)fieldAssignment.getFieldDefinition(); final RoleFieldModel roleFieldModel = new RoleFieldModel(roleField); final List<RoleFieldModel> otherRoleFieldModels = RoleFieldModel.wrapInRoleFieldModels(roleField.getFieldsForOtherRoles()); final boolean allowRemove = !roleField.getEditMode().isNoEdit(); add(new FieldDefinitionLabel("fieldLabel", new FieldDefinitionModel(roleField))); // set up container this.fieldValuesContainer = new WebMarkupContainer("fieldValuesContainer"); fieldValuesContainer.setOutputMarkupId(true); add(fieldValuesContainer); // add feedback panel this.feedbackPanel = new FeedbackPanel("feedback", new AbstractFieldInstancePanelFeedbackMessageFilter()); feedbackPanel.setOutputMarkupId(true); fieldValuesContainer.add(feedbackPanel); // add field values component(s) Comparator<Object> comparator = new RoleFieldsValueComparator(new TopicModel<Topic>(fieldInstance.getInstance()), otherRoleFieldModels); this.fieldValuesModel = new FieldValuesModel(fieldInstanceModel, comparator); this.listView = new ListView<FieldValueModel>("fieldValues", fieldValuesModel) { @Override protected void onBeforeRender() { validateCardinality(); super.onBeforeRender(); } public void populateItem(final ListItem<FieldValueModel> item) { FieldValueModel fieldValueModel = item.getModelObject(); // TODO: make sure non-existing value field gets focus if last edit happened there final WebMarkupContainer fieldValueButtons = new WebMarkupContainer("fieldValueButtons"); fieldValueButtons.setOutputMarkupId(true); item.add(fieldValueButtons); FieldInstanceRemoveButton removeButton = new FieldInstanceRemoveButton("remove", "remove-value.gif", fieldValueModel) { @Override public boolean isVisible() { boolean visible = !readonly && fieldValueModel.isExistingValue() && allowRemove; if (visible) { // filter by player AbstractOntopolyPage page = (AbstractOntopolyPage)getPage(); RoleField.ValueIF value = (RoleField.ValueIF)fieldValueModel.getObject(); Topic[] players = value.getPlayers(); for (int i=0; i < players.length; i++) { if (!page.filterTopic(players[i])) return false; } // // show remove button on 1:1 field unless just one value left // FieldInstance fi = fieldValueModel.getFieldInstanceModel().getFieldInstance(); // Cardinality cardinality = fi.getFieldAssignment().getCardinality(); // if (cardinality.isMinOne() && cardinality.isMaxOne() && // ((fieldValuesModel.size() == 1 && !fieldValuesModel.getShowExtraField()) || // (fieldValuesModel.size() == 2 && fieldValuesModel.getShowExtraField()))) // return false; } return visible; } @Override public void onClick(AjaxRequestTarget target) { FieldInstance fieldInstance = fieldValueModel.getFieldInstanceModel().getFieldInstance(); Object value = fieldValueModel.getObject(); Topic currentTopic = fieldInstance.getInstance(); RoleField currentField = (RoleField)fieldInstance.getFieldAssignment().getFieldDefinition(); RoleField.ValueIF valueIf = (RoleField.ValueIF)value; RoleField[] fields = valueIf.getRoleFields(); // check with page to see if add is allowed boolean removeAllowed = true; AbstractOntopolyPage page = (AbstractOntopolyPage)getPage(); for (int i=0; i < fields.length; i++) { RoleField selectedField = fields[i]; if (ObjectUtils.different(currentField, selectedField)) { Topic selectedTopic = valueIf.getPlayer(selectedField, fieldInstance.getInstance()); if (!page.isRemoveAllowed(currentTopic, currentField, selectedTopic, selectedField)) { removeAllowed = false; } } } // perform removal if (removeAllowed) { fieldInstance.removeValue(value, page.getListener()); listView.removeAll(); updateDependentComponents(target); } } }; fieldValueButtons.add(removeButton); // n-ary FieldInstanceAssociationNaryField naryField = new FieldInstanceAssociationNaryField("fieldValue", FieldInstanceAssociationNaryPanel.this, roleFieldModel, otherRoleFieldModels, fieldValueModel, fieldsViewModel, readonly, traversable, arity); item.add(naryField); addNewFieldValueCssClass(item, fieldValuesModel, fieldValueModel); } }; listView.setReuseItems(true); fieldValuesContainer.add(listView); // figure out which buttons to show this.fieldInstanceButtons = new WebMarkupContainer("fieldInstanceButtons"); fieldInstanceButtons.setOutputMarkupId(true); add(fieldInstanceButtons); // "add" button OntopolyImageLink addButton = new OntopolyImageLink("add", "add.gif") { @Override public void onClick(AjaxRequestTarget target) { boolean showExtraField = !fieldValuesModel.getShowExtraField(); fieldValuesModel.setShowExtraField(showExtraField, true); listView.removeAll(); updateDependentComponents(target); } @Override public boolean isVisible() { if (readonly) return false; // Cardinality cardinality = fieldValuesModel.getFieldInstanceModel().getFieldInstance().getFieldAssignment().getCardinality(); // return !(cardinality.isMaxOne() && fieldValuesModel.getNumberOfValues() > 1); return fieldValuesModel.containsExisting(); } @Override public String getImage() { return fieldValuesModel.getShowExtraField() ? "remove.gif" : "add.gif"; } @Override public IModel<String> getTitleModel() { return new ResourceModel(fieldValuesModel.getShowExtraField() ? "icon.remove.hide-field" : "icon.add.add-value"); } }; fieldInstanceButtons.add(addButton); } }