/*
* #!
* 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.AssociationIF;
import net.ontopia.topicmaps.core.AssociationRoleIF;
import net.ontopia.topicmaps.core.TopicIF;
import net.ontopia.topicmaps.core.TypedIF;
import net.ontopia.utils.DeciderIF;
import net.ontopia.topicmaps.nav2.core.ContextManagerIF;
import net.ontopia.topicmaps.nav2.core.NavigatorRuntimeException;
import net.ontopia.topicmaps.nav2.taglibs.value.BaseScopedTag;
/**
* INTERNAL: Value producing tag that finds all the topics associated
* with this the topics in the input collection, subject to some
* constraints.
*/
public class AssociatedTag extends BaseScopedTag {
// tag attributes
protected String startrole;
protected String endrole;
protected String assoctype;
protected String totopic;
protected boolean produceTopics = true;
public Collection process(Collection topics) throws JspTagException {
if (topics == null || topics.isEmpty())
return Collections.EMPTY_SET;
else{
ContextManagerIF ctxtMgr = contextTag.getContextManager();
Collection startroles = getValue(ctxtMgr, startrole);
Collection endroles = getValue(ctxtMgr, endrole);
Collection assoctypes = getValue(ctxtMgr, assoctype);
Collection totopics = getValue(ctxtMgr, totopic);
Collection associated = new HashSet();
// setup scope filter for user context filtering
DeciderIF scopeDecider = null;
if (useUserContextFilter)
scopeDecider = getScopeDecider(SCOPE_ASSOCIATIONS);
try {
for (Iterator it = topics.iterator(); it.hasNext(); ) {
TopicIF start = (TopicIF) it.next();
for (Iterator roles = start.getRoles().iterator(); roles.hasNext(); ) {
AssociationRoleIF role = (AssociationRoleIF) roles.next();
if (!isInstanceOf(role, startroles))
continue;
AssociationIF assoc = role.getAssociation();
if (!isInstanceOf(assoc, assoctypes))
continue;
for (Iterator roles2 = assoc.getRoles().iterator(); roles2.hasNext();){
AssociationRoleIF role2 = (AssociationRoleIF) roles2.next();
if (role2.equals(role) ||
!isInstanceOf(role2, endroles))
continue;
TopicIF currentPlayer = role2.getPlayer();
if (totopics != null && !totopics.contains(currentPlayer))
continue;
if (currentPlayer != null) {
// add current player if within user context if specified
if (scopeDecider == null || scopeDecider.ok(currentPlayer)) {
if (produceTopics)
associated.add(currentPlayer);
else
associated.add(assoc);
}
}
} // for roles2
} // for roles
} // for it
} catch (ClassCastException e) {
throw new NavigatorRuntimeException("'associated' tag got a collection containing non-topic objects.", e);
}
return associated;
}
}
// -----------------------------------------------------------------
// internal helpers
// -----------------------------------------------------------------
protected boolean isInstanceOf(TypedIF object, Collection types) {
if (types == null)
return true;
return types.contains(object.getType());
}
protected Collection getValue(ContextManagerIF ctxtMgr, String var)
throws NavigatorRuntimeException {
if (var == null)
return null;
return ctxtMgr.getValue(var);
}
// -----------------------------------------------------------------
// set methods for tag attributes
// -----------------------------------------------------------------
public void setStartrole(String startrole) {
this.startrole = startrole;
}
public void setEndrole(String endrole) {
this.endrole = endrole;
}
public void setType(String type) {
this.assoctype = type;
}
public void setFrom(String from) {
this.variableName = from;
}
public void setTo(String to) {
this.totopic = to;
}
public void setProduce(String produce) {
if (produce.equals("topics"))
produceTopics = true;
else if (produce.equals("associations"))
produceTopics = false;
else
throw new IllegalArgumentException("Invalid value for 'produce' attribute of element 'associated' tag: <" + produce + ">");
}
}