/*
* #!
* 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.model;
import java.util.Collection;
import java.util.Iterator;
import net.ontopia.infoset.core.LocatorIF;
import net.ontopia.topicmaps.core.AssociationIF;
import net.ontopia.topicmaps.core.OccurrenceIF;
import net.ontopia.topicmaps.core.TopicIF;
import net.ontopia.utils.CollectionUtils;
import ontopoly.utils.OntopolyModelUtils;
/**
* Represents a field type, which may be a name type, an occurrence type, an
* identity field, or a combination of an association role and an association
* type.
*/
public abstract class FieldDefinition extends Topic {
public static final int FIELD_TYPE_ROLE = 1;
public static final int FIELD_TYPE_OCCURRENCE = 2;
public static final int FIELD_TYPE_NAME = 4;
public static final int FIELD_TYPE_IDENTITY = 8;
public static final int FIELD_TYPE_QUERY = 16;
private Cardinality cachedCardinality;
protected FieldDefinition(TopicIF topic, TopicMap tm) {
super(topic, tm);
}
/**
* @return an int that identifies this fieldType
*/
public abstract int getFieldType();
/**
* Returns the name of this field definition.
*/
public abstract String getFieldName();
public abstract LocatorIF getLocator();
public ViewModes getViewModes(FieldsView view) {
return new ViewModes(this, view);
}
public FieldsView getValueView(FieldsView view) {
TopicMap tm = getTopicMap();
TopicIF aType = OntopolyModelUtils.getTopicIF(tm, PSI.ON_USE_VALUE_VIEW);
TopicIF rType1 = OntopolyModelUtils.getTopicIF(tm, PSI.ON_FIELD_DEFINITION);
TopicIF player1 = getTopicIF();
TopicIF rType2 = OntopolyModelUtils.getTopicIF(tm, PSI.ON_PARENT_VIEW);
TopicIF player2 = view.getTopicIF();
TopicIF rType3 = OntopolyModelUtils.getTopicIF(tm, PSI.ON_CHILD_VIEW);
Collection<TopicIF> players = OntopolyModelUtils.findTernaryPlayers(tm, aType, player1, rType1, player2, rType2, rType3);
TopicIF viewIf = CollectionUtils.getFirst(players);
if (viewIf == null) {
return FieldsView.getDefaultFieldsView(tm);
} else {
return new FieldsView(viewIf, tm);
}
}
/**
* Returns the cardinality of the field on this topic type.
*/
public Cardinality getCardinality() {
if (cachedCardinality == null) {
TopicIF cardinalityIf = OntopolyModelUtils.findBinaryPlayer(getTopicMap(),
PSI.ON_HAS_CARDINALITY, getTopicIF(), PSI.ON_FIELD_DEFINITION, PSI.ON_CARDINALITY);
this.cachedCardinality = (cardinalityIf == null ? Cardinality.getDefaultCardinality(this) : new Cardinality(cardinalityIf, getTopicMap()));
}
return cachedCardinality;
}
/**
* Sets the cardinality of the field on this topic type.
*/
public void setCardinality(Cardinality cardinality) {
// NOTE: used by FieldsEditor
TopicMap tm = getTopicMap();
TopicIF aType = OntopolyModelUtils.getTopicIF(tm, PSI.ON_HAS_CARDINALITY);
TopicIF type2 = OntopolyModelUtils.getTopicIF(tm, PSI.ON_FIELD_DEFINITION);
TopicIF type3 = OntopolyModelUtils.getTopicIF(tm, PSI.ON_CARDINALITY);
TopicIF player2 = getTopicIF();
TopicIF player3 = cardinality.getTopicIF();
Collection<AssociationIF> associationIFs = OntopolyModelUtils.findBinaryAssociations(
tm, aType, player2, type2, type3);
Iterator<AssociationIF> it = associationIFs.iterator();
while (it.hasNext()) {
it.next().remove();
}
OntopolyModelUtils.makeBinaryAssociation(aType, player2,
type2, player3, type3);
cachedCardinality = cardinality;
}
/**
* Returns the validation type.
*/
public String getValidationType() {
TopicIF oType = OntopolyModelUtils.getTopicIF(getTopicMap(), PSI.ON_VALIDATION_TYPE);
OccurrenceIF occ = OntopolyModelUtils.findOccurrence(oType, getTopicIF());
return occ == null ? null : occ.getValue();
}
public abstract Collection<? extends Object> getValues(Topic topic);
public abstract void addValue(Topic topic, Object _value, LifeCycleListener listener);
public abstract void removeValue(Topic topic, Object _value, LifeCycleListener listener);
public boolean equals(Object obj) {
if (!(obj instanceof FieldDefinition))
return false;
FieldDefinition other = (FieldDefinition)obj;
return getTopicIF().equals(other.getTopicIF());
}
public int hashCode() {
return getTopicIF().hashCode();
}
private static int getFieldType(TopicIF fieldTopic) {
for (TopicIF topicType : fieldTopic.getTypes()) {
Collection<LocatorIF> psis = topicType.getSubjectIdentifiers();
if (psis.contains(PSI.ON_NAME_FIELD))
return FieldDefinition.FIELD_TYPE_NAME;
else if (psis.contains(PSI.ON_IDENTITY_FIELD))
return FieldDefinition.FIELD_TYPE_IDENTITY;
else if (psis.contains(PSI.ON_OCCURRENCE_FIELD))
return FieldDefinition.FIELD_TYPE_OCCURRENCE;
else if (psis.contains(PSI.ON_ROLE_FIELD))
return FieldDefinition.FIELD_TYPE_ROLE;
else if (psis.contains(PSI.ON_QUERY_FIELD))
return FieldDefinition.FIELD_TYPE_QUERY;
}
throw new RuntimeException("Not a field definition: " + fieldTopic);
}
public static FieldDefinition getFieldDefinition(String fieldId, TopicMap tm) {
TopicIF fieldTopic = tm.getTopicIFById(fieldId);
if (fieldTopic == null)
throw new RuntimeException("Could not find field with id '" + fieldId + "'");
int fieldType = getFieldType(fieldTopic);
return getFieldDefinition(fieldId, fieldType, tm);
}
public static FieldDefinition getFieldDefinition(String fieldId, int fieldType, TopicMap tm) {
TopicIF fieldTopic = tm.getTopicIFById(fieldId);
if (fieldTopic == null)
throw new RuntimeException("Could not find field with id '" + fieldId + "'");
return getFieldDefinition(fieldTopic, fieldType, tm);
}
public static FieldDefinition getFieldDefinition(TopicIF fieldTopic, TopicMap tm) {
int fieldType = getFieldType(fieldTopic);
return getFieldDefinition(fieldTopic, fieldType, tm);
}
private static FieldDefinition getFieldDefinition(TopicIF fieldTopic, int fieldType, TopicMap tm) {
switch (fieldType) {
case FieldDefinition.FIELD_TYPE_ROLE:
return new RoleField(fieldTopic, tm);
case FieldDefinition.FIELD_TYPE_OCCURRENCE:
return new OccurrenceField(fieldTopic, tm);
case FieldDefinition.FIELD_TYPE_NAME:
return new NameField(fieldTopic, tm);
case FieldDefinition.FIELD_TYPE_IDENTITY:
return new IdentityField(fieldTopic, tm);
case FieldDefinition.FIELD_TYPE_QUERY:
return new QueryField(fieldTopic, tm);
default:
throw new RuntimeException("Unknown field type: " + fieldType);
}
}
}