/*
* #!
* 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.Collections;
import java.util.Iterator;
import java.util.List;
import net.ontopia.infoset.core.LocatorIF;
import net.ontopia.topicmaps.core.OccurrenceIF;
import net.ontopia.topicmaps.core.TopicIF;
import ontopoly.utils.OntopolyModelUtils;
/**
* Represents an occurrence field.
*/
public class OccurrenceField extends FieldDefinition {
private OccurrenceType occurrenceType;
public OccurrenceField(TopicIF topic, TopicMap tm) {
this(topic, tm, null);
}
public OccurrenceField(TopicIF topic, TopicMap tm, OccurrenceType occurrenceType) {
super(topic, tm);
this.occurrenceType = occurrenceType;
}
@Override
public int getFieldType() {
return FIELD_TYPE_OCCURRENCE;
}
@Override
public String getFieldName() {
return getTopicMap().getTopicName(getTopicIF(), getOccurrenceType());
}
@Override
public LocatorIF getLocator() {
return PSI.ON_OCCURRENCE_FIELD;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof OccurrenceField))
return false;
OccurrenceField other = (OccurrenceField)obj;
return (getTopicIF().equals(other.getTopicIF()));
}
/**
* Gets the occurrence type to which this field is assigned.
*
* @return the occurrence type.
*/
public OccurrenceType getOccurrenceType() {
if (occurrenceType == null) {
TopicIF occurrenceTypeIf = OntopolyModelUtils.findBinaryPlayer(getTopicMap(),
PSI.ON_HAS_OCCURRENCE_TYPE, getTopicIF(), PSI.ON_OCCURRENCE_FIELD, PSI.ON_OCCURRENCE_TYPE);
this.occurrenceType = (occurrenceTypeIf == null ? null : new OccurrenceType(occurrenceTypeIf, getTopicMap()));
}
return occurrenceType;
}
/**
* Returns the data type of the occurrence type.
*/
public DataType getDataType() {
TopicIF dataTypeIf = OntopolyModelUtils.findBinaryPlayer(getTopicMap(),
PSI.ON_HAS_DATATYPE, getTopicIF(), PSI.ON_FIELD_DEFINITION, PSI.ON_DATATYPE);
return dataTypeIf == null ? DataType.getDefaultDataType(getTopicMap()) : new DataType(dataTypeIf, getTopicMap());
}
/**
* Returns the assigned height of the occurrence text field.
*/
public int getHeight() {
TopicIF oType = OntopolyModelUtils.getTopicIF(getTopicMap(), PSI.ON_HEIGHT);
OccurrenceIF occ = OntopolyModelUtils.findOccurrence(oType, getTopicIF());
return (occ == null ? 1 : Integer.parseInt(occ.getValue()));
}
/**
* Returns the assigned width of the occurrence text field.
*/
public int getWidth() {
TopicIF oType = OntopolyModelUtils.getTopicIF(getTopicMap(), PSI.ON_WIDTH);
OccurrenceIF occ = OntopolyModelUtils.findOccurrence(oType, getTopicIF());
return (occ == null ? 50 : Integer.parseInt(occ.getValue()));
}
@Override
public List<OccurrenceIF> getValues(Topic topic) {
TopicIF topicIf = topic.getTopicIF();
OccurrenceType otype = getOccurrenceType();
if (otype == null) return Collections.emptyList();
TopicIF typeIf = otype.getTopicIF();
// FIXME: need to figure out how to do datatypes properly
//! LocatorIF datatype = getDataType().getLocator();
// HACK: we're ignoring the datatype when looking up existing ones
// return OntopolyModelUtils.findOccurrences(getTopicIF(), topicIf,
// datatype, Collections.EMPTY_SET);
Collection<TopicIF> scope = Collections.emptySet();
return OntopolyModelUtils.findOccurrences(typeIf, topicIf, scope);
}
@Override
public void addValue(Topic topic, Object _value, LifeCycleListener listener) {
TopicIF topicIf = topic.getTopicIF();
String value = (String) _value;
LocatorIF datatype = getDataType().getLocator();
OccurrenceType otype = getOccurrenceType();
if (otype == null) return;
TopicIF typeIf = otype.getTopicIF();
// HACK: we're ignoring the datatype when looking up existing ones
// Collection occs = OntopolyModelUtils.findOccurrences(getTopicIF(),
// topicIf, value, datatype, Collections.EMPTY_SET);
Collection<TopicIF> scope = Collections.emptySet();
Collection<OccurrenceIF> occs = OntopolyModelUtils.findOccurrences(typeIf, topicIf, value, scope);
if (occs.isEmpty()) {
// create new
OntopolyModelUtils.makeOccurrence(typeIf, topicIf, value, datatype, scope);
} else {
// remove all except the first one
Iterator<OccurrenceIF> iter = occs.iterator();
iter.next(); // skip first
while (iter.hasNext()) {
OccurrenceIF occ = iter.next();
occ.remove();
}
}
if (listener != null) listener.onAfterAdd(topic, this, value);
}
@Override
public void removeValue(Topic topic, Object _value, LifeCycleListener listener) {
TopicIF topicIf = topic.getTopicIF();
String value = (_value instanceof OccurrenceIF ? ((OccurrenceIF) _value)
.getValue() : (String) _value);
// LocatorIF datatype = getDataType().getLocator();
OccurrenceType otype = getOccurrenceType();
if (otype == null) return;
TopicIF typeIf = otype.getTopicIF();
if (listener != null) listener.onBeforeRemove(topic, this, value);
// HACK: we're ignoring the datatype when looking up existing ones
// Collection occs = OntopolyModelUtils.findOccurrences(typeIf,
// topicIf, value, datatype, Collections.EMPTY_SET);
Collection<TopicIF> scope = Collections.emptySet();
Collection<OccurrenceIF> occs = OntopolyModelUtils.findOccurrences(typeIf, topicIf, value, scope);
if (!occs.isEmpty()) {
// remove all the matching
Iterator<OccurrenceIF> iter = occs.iterator();
while (iter.hasNext()) {
OccurrenceIF occ = iter.next();
occ.remove();
}
}
}
}