/*
* #!
* Ontopia Engine
* #-
* 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 net.ontopia.topicmaps.utils.deciders;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import net.ontopia.topicmaps.core.AssociationIF;
import net.ontopia.topicmaps.core.AssociationRoleIF;
import net.ontopia.topicmaps.core.TopicNameIF;
import net.ontopia.topicmaps.core.OccurrenceIF;
import net.ontopia.topicmaps.core.ScopedIF;
import net.ontopia.topicmaps.core.TopicIF;
import net.ontopia.topicmaps.core.VariantNameIF;
import net.ontopia.utils.DeciderIF;
/**
* INTERNAL: Accepts or rejects topic map constructs based on their
* relations to other topic map constructs and a filter that makes
* decisions on an individual basis. Used by the topic map exporters
* to support topic filtering.
*/
public class TMExporterDecider implements DeciderIF<Object> {
// Decides whether individual TMObjectIFs should be accepted or rejected.
private DeciderIF<Object> filter;
/**
* Creates a new TMExporterDecider.
* @param filter accepts or rejects an individual object
*/
public TMExporterDecider(DeciderIF<Object> filter) {
if (filter == null)
throw new NullPointerException("Filter cannot be null.");
this.filter = filter;
}
/**
* Accepts or rejects AssociationIFs, TopicNameIFs, Collections, OccurrenceIFs,
* TopicIFs and VariantNameIFs, base on the filter and their relations to
* other objects. @param object The object to accept or reject.
*/
public boolean ok(Object object) {
// Check that none of the scoping topics are disallowed.
if (object instanceof ScopedIF) {
ScopedIF scoped = (ScopedIF)object;
Iterator<TopicIF> scopeIt = scoped.getScope().iterator();
while (scopeIt.hasNext())
if (!ok(scopeIt.next()))
return false;
}
if (object instanceof AssociationIF)
return ok((AssociationIF)object);
if (object instanceof TopicNameIF)
return ok((TopicNameIF)object);
if (object instanceof Collection)
return ok((Collection<?>)object);
if (object instanceof OccurrenceIF)
return ok((OccurrenceIF)object);
if (object instanceof TopicIF)
return ok((TopicIF)object);
if (object instanceof VariantNameIF)
return ok((VariantNameIF)object);
return true;
}
/**
* Accepts or rejects a TopicNameIF
* @param baseName to be accepted/rejected.
* @return true iff baseName is accepted by the filter and its scope is also
* accepted by the filter.
*/
public boolean ok(TopicNameIF baseName) {
return filter.ok(baseName) && filter.ok(baseName.getScope());
}
/**
* Accepts or rejects a VariantNameIF
* @param variantName to be accepted/rejected.
* @return true iff variantName is accepted by the filter and its scope is
* also accepted by the filter.
*/
public boolean ok(VariantNameIF variantName) {
return filter.ok(variantName) && filter.ok(variantName.getScope());
}
/**
* Return true iff the association type, each role player and each role type
* are accepted.
* @param association the association to test for acceptance.
* @return true iff the association is accepted.
*/
public boolean ok(AssociationIF association) {
boolean retVal = ok(association.getType());
Iterator<AssociationRoleIF> rolesIt = association.getRoles().iterator();
while (rolesIt.hasNext()) {
AssociationRoleIF role = rolesIt.next();
retVal &= ok(role.getType()) && filter.ok(role.getPlayer())
&& filter.ok(role);
}
return retVal;
}
/**
* Return true iff the type of the occurrence is accepted
* @param occurrence The occurence to test for acceptance. It is assumed that
* occurrence will only be tested for acceptance if its parent topic
* has already been tested and passed.
* @return true iff occurrence is accepted.
*/
public boolean ok(OccurrenceIF occurrence) {
return filter.ok(occurrence) && ok(occurrence.getType())
&& ok(occurrence.getScope()) && ok(occurrence.getTopic());
}
/**
* Return true iff the given topic, all of it's types and all types of the
* types (etc. recursively) are accepted by the filter that was given in the
* constructor.
* @param topic The topic to test for acceptance.
* @return true iff the topic is accepted.
*/
public boolean ok(TopicIF topic) {
return ok(topic, new ArrayList<TopicIF>());
}
/**
* Accepts or rejects a collection of TopicsIFs.
* @param coll The collection to test (search)
* @return true iff whole collection of topics are accepted by filter.
*/
private boolean ok(Collection<?> coll) {
Iterator<?> it = coll.iterator();
while (it.hasNext())
if (!ok(it.next()))
return false;
return true;
}
/**
* Return true iff the given topic, all of it's types and all types of the
* types (etc. recursively) are accepted by the filter that was given in the
* constructor.
* @param topic The topic to test for acceptance.
* @param checked Topics that have already been checked (passed).
* @return true iff the topic is accepted.
*/
private boolean ok(TopicIF topic, Collection<TopicIF> checked) {
// Only check each topic once.
if (checked.contains(topic))
return true;
if (topic == null)
return true;
if (filter.ok(topic))
checked.add(topic);
else
return false;
return true;
}
}