/* * #! * Ontopia Navigator * #- * 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.nav2.taglibs.TMvalue; import java.util.HashSet; import java.util.Collection; import java.util.Collections; import java.util.Iterator; import javax.servlet.jsp.JspTagException; import net.ontopia.topicmaps.core.TopicIF; import net.ontopia.topicmaps.core.AssociationIF; import net.ontopia.topicmaps.core.AssociationRoleIF; import net.ontopia.utils.DeciderIF; import net.ontopia.topicmaps.nav2.utils.NavigatorUtils; import net.ontopia.topicmaps.nav2.core.NavigatorRuntimeException; import net.ontopia.topicmaps.nav2.taglibs.value.BaseScopedTag; /** * INTERNAL: Value Producing Tag for finding all the association * roles of all the topics and associations in a collection. */ public class RolesTag extends BaseScopedTag { // constants public static final String BINARY = "binary"; public static final String NARY = "nary"; // tag attributes private String cardinality = null; private String varRemoveColl = null; public Collection process(Collection tmObjects) throws JspTagException { // find all base names of all tmObjects in collection // avoid duplicate type entries therefore use a HashSet if (tmObjects == null || tmObjects.isEmpty()) return Collections.EMPTY_SET; else { HashSet assocRoles = new HashSet(); // retrieve collection which should be subtracted Collection excludedTopics = (varRemoveColl == null ? null : contextTag.getContextManager().getValue(varRemoveColl)); DeciderIF scopeDecider = null; // setup scope filter for user context filtering if (useUserContextFilter) scopeDecider = getScopeDecider(SCOPE_ASSOCIATIONS); // loop over input collection Iterator iter = tmObjects.iterator(); Object obj = null; while (iter.hasNext()) { obj = iter.next(); // --- for topic objects if (obj instanceof TopicIF) { TopicIF topic = (TopicIF) obj; // System.out.println("RolesTag for topic " + topic ); Collection _roles = topic.getRoles(); if (checkCardinality(_roles.size())) { Iterator itRoles = _roles.iterator(); while (itRoles.hasNext()) { AssociationRoleIF assocRole = (AssociationRoleIF) itRoles.next(); if (scopeDecider != null && !scopeDecider.ok(assocRole.getAssociation())) continue; if (excludedTopics == null || !excludedTopics.contains(assocRole.getPlayer())) assocRoles.add( assocRole ); } } } // --- for association objects else if (obj instanceof AssociationIF) { AssociationIF assoc = (AssociationIF) obj; // System.out.println("RolesTag for assoc " + assoc ); Collection _roles = assoc.getRoles(); if (checkCardinality(_roles.size())) { Iterator itRoles = _roles.iterator(); while (itRoles.hasNext()) { AssociationRoleIF assocRole = (AssociationRoleIF) itRoles.next(); if (scopeDecider != null && !scopeDecider.ok(assocRole.getAssociation())) continue; if (excludedTopics == null || !excludedTopics.contains(assocRole.getPlayer())) assocRoles.add( assocRole ); } } } else { String msg = "RolesTag: only support instances of TopicIF or " + "AssociationIF, but got " + obj.getClass().getName(); throw new NavigatorRuntimeException(msg); } } // while iter return assocRoles; } } /** * INTERNAL: returns true if claimed cardinality is kept, otherwise * false. */ private final boolean checkCardinality(int nrOfPlayers) { if (cardinality == null) return true; if (cardinality.equals(BINARY)) return (nrOfPlayers == 2); if (cardinality.equals(NARY)) return (nrOfPlayers > 2); return false; } // ------------------------------------------------------- // set methods for tag attributes // ------------------------------------------------------- /** * Sets the variable name of an input collection consisting of one * or more topics that will removed from the retrieved list of * association role players. */ public void setRemove(String varRemoveTopicColl) { this.varRemoveColl = varRemoveTopicColl; } /** * Specify in which cardinality you are interested. This filters out * the association roles retrieved for the input collection * (consisting of TopicIF and AssociationIF objects). If not * specified any kind of cardinality is returned. Allowed values * are "binary", "nary" (means at least trenary). */ public void setCardinality(String cardinality) { // FIXME: Should support "unary" as well. if (cardinality.equals(BINARY) || cardinality.equals(NARY)) this.cardinality = cardinality; else throw new IllegalArgumentException("RolesTag: not allowed value specified" + " for attribute 'cardinality'."); } }