/*
* #!
* 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.List;
import ontopoly.model.FieldInstance;
import ontopoly.model.InterfaceControl;
import ontopoly.model.RoleField;
import ontopoly.model.Topic;
import ontopoly.model.TopicType;
import ontopoly.models.FieldInstanceModel;
import ontopoly.models.FieldValueModel;
import ontopoly.models.FieldsViewModel;
import ontopoly.models.PossiblePlayersModel;
import ontopoly.models.RoleFieldModel;
import ontopoly.models.TopicModel;
import ontopoly.pages.AbstractOntopolyPage;
import ontopoly.utils.OntopolyUtils;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.FormComponent;
import org.apache.wicket.markup.html.panel.Panel;
public abstract class FieldInstanceAssociationBinaryField extends Panel {
private FormComponent<Topic> formComponent;
public FieldInstanceAssociationBinaryField(String id,
final RoleFieldModel valueFieldModel,
final FieldValueModel fieldValueModel, FieldsViewModel fieldsViewModel,
final boolean readonly, boolean embedded, boolean traversable, boolean allowAdd) {
super(id);
FieldInstanceModel fieldInstanceModel = fieldValueModel.getFieldInstanceModel();
RoleField valueField = valueFieldModel.getRoleField();
if (fieldValueModel.isExistingValue()) {
RoleField.ValueIF value = (RoleField.ValueIF)fieldValueModel.getObject();
Topic oPlayer = value.getPlayer(valueField, fieldInstanceModel.getFieldInstance().getInstance());
if (embedded) {
TopicType defaultTopicType = OntopolyUtils.getDefaultTopicType(oPlayer);
List<FieldInstance> fieldInstances = oPlayer.getFieldInstances(defaultTopicType, fieldsViewModel.getFieldsView());
// if no matching fields show link to topic instead
if (fieldInstances.isEmpty()) {
// player link
TopicLink<Topic> playerLink = new TopicLink<Topic>("player", new TopicModel<Topic>(oPlayer), fieldsViewModel);
playerLink.setEnabled(traversable);
add(playerLink);
} else {
// embedded topic
List<FieldInstanceModel> fieldInstanceModels = FieldInstanceModel.wrapInFieldInstanceModels(fieldInstances);
FieldInstancesPanel fip = new FieldInstancesPanel("player", fieldInstanceModels, fieldsViewModel, readonly, traversable);
fip.setRenderBodyOnly(true);
add(fip);
}
} else {
// player link
TopicLink<Topic> playerLink = new TopicLink<Topic>("player", new TopicModel<Topic>(oPlayer), fieldsViewModel);
playerLink.setEnabled(traversable);
add(playerLink);
}
} else {
InterfaceControl interfaceControl = valueField.getInterfaceControl();
if (readonly || interfaceControl.isSearchDialog() || interfaceControl.isBrowseDialog() || !allowAdd) {
add(new Label("player").setVisible(false));
} else if (interfaceControl.isDropDownList()) {
// default is drop-down list
TopicModel<Topic> selectedModel = new TopicModel<Topic>(null);
PossiblePlayersModel choicesModel = new PossiblePlayersModel(fieldInstanceModel, valueFieldModel) {
@Override
protected void filterPlayers(Collection<Topic> players) {
AbstractOntopolyPage page = (AbstractOntopolyPage)getPage();
page.filterTopics(players);
}
};
TopicDropDownChoice<Topic> choice = new TopicDropDownChoice<Topic>("player", selectedModel, choicesModel) {
@Override
protected void onModelChanged() {
super.onModelChanged();
FieldInstanceAssociationBinaryField.this.onNewSelection(fieldValueModel, (Topic)getModelObject());
}
};
add(choice);
this.formComponent = choice;
} else if (interfaceControl.isAutoComplete()) {
AssociationFieldAutoCompleteTextField autoCompleteField
= new AssociationFieldAutoCompleteTextField("player", new TopicModel<Topic>(null), valueFieldModel) {
@Override
protected void filterPlayers(List<Topic> players) {
AbstractOntopolyPage page = (AbstractOntopolyPage)getPage();
page.filterTopics(players);
}
@Override
protected void onTopicSelected(Topic topic) {
FieldInstanceAssociationBinaryField.this.onNewSelection(fieldValueModel, topic);
}
};
autoCompleteField.setOutputMarkupId(true);
add(autoCompleteField);
this.formComponent = autoCompleteField.getTextField();
} else {
throw new RuntimeException("Unsupported interface control: " + interfaceControl);
}
}
}
protected void onNewSelection(FieldValueModel fieldValueModel, Topic selectedTopic) {
FieldInstanceModel fieldInstanceModel = fieldValueModel.getFieldInstanceModel();
FieldInstance fieldInstance = fieldInstanceModel.getFieldInstance();
Topic currentTopic = fieldInstance.getInstance();
RoleField currentField = (RoleField)fieldInstance.getFieldAssignment().getFieldDefinition();
RoleField selectedField = getOtherBinaryRoleField(currentField);
// check with page to see if add is allowed
AbstractOntopolyPage page = (AbstractOntopolyPage)getPage();
if (page.isAddAllowed(currentTopic, currentField, selectedTopic, selectedField)) {
performNewSelection(fieldValueModel, selectedField, selectedTopic);
}
}
protected abstract void performNewSelection(FieldValueModel fieldValueModel, RoleField selectedField, Topic selectedTopic);
protected RoleField getOtherBinaryRoleField(RoleField thisField) {
Collection<RoleField> otherRoleFields = thisField.getFieldsForOtherRoles();
if (otherRoleFields.size() != 1)
throw new RuntimeException("Binary association does not have two fields.");
RoleField otherField = otherRoleFields.iterator().next();
return otherField;
}
public FormComponent<Topic> getUpdateableComponent() {
return formComponent;
}
}