/* * #! * 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.portlets.taglib; import java.util.List; import java.util.Collection; import java.util.Set; import javax.servlet.jsp.PageContext; import javax.servlet.jsp.JspException; import javax.servlet.jsp.JspTagException; import javax.servlet.jsp.tagext.TagSupport; import net.ontopia.topicmaps.core.TopicIF; import net.ontopia.topicmaps.nav2.core.VariableNotSetException; import net.ontopia.topicmaps.nav2.utils.FrameworkUtils; import net.ontopia.topicmaps.nav2.taglibs.logic.ContextTag; import net.ontopia.topicmaps.nav2.impl.framework.InteractionELSupport; import net.ontopia.topicmaps.nav2.utils.FrameworkUtils; import net.ontopia.topicmaps.nav2.portlets.pojos.RelatedTopics; import net.ontopia.utils.OntopiaRuntimeException; import net.ontopia.utils.CompactHashSet; public class RelatedTag extends TagSupport { private RelatedTopics related; private String var; private String topic; private String hideassocs; private String exclassocs; private String exclroles; private String excltopics; private String inclassocs; private String incltopics; private String filterQuery; private String headingOrderQuery; private int headingOrdering = RelatedTopics.ORDERING_ASC; private String childOrderQuery; private int childOrdering = RelatedTopics.ORDERING_ASC; private boolean aggregateHierarchy; private String aggregateAssociations; private int maxChildren = -1; public int doStartTag() throws JspTagException { ContextTag contextTag = FrameworkUtils.getContextTag(pageContext); if (related == null) buildModel(contextTag); TopicIF topic = (TopicIF) getVariableValue(this.topic); if (topic == null) throw new JspTagException("Couldn't find topic '" + topic + "'"); List headings = related.makeModel(topic); pageContext.setAttribute(var, headings, PageContext.REQUEST_SCOPE); // FIXME: make new scope here if (contextTag != null) contextTag.getContextManager().setValue(var, headings); return EVAL_BODY_INCLUDE; } public int doEndTag() throws JspException { related = null; // without this line config changes are never picked up // need to think about how/whether to make this more // efficient return EVAL_PAGE; } public void release() { this.related = null; this.var = null; this.topic = null; this.hideassocs = null; this.exclassocs = null; this.exclroles = null; this.excltopics = null; this.inclassocs = null; this.incltopics = null; this.filterQuery = null; this.headingOrderQuery = null; this.headingOrdering = RelatedTopics.ORDERING_ASC; this.childOrderQuery = null; this.childOrdering = RelatedTopics.ORDERING_ASC; this.aggregateHierarchy = false; this.aggregateAssociations = null; this.maxChildren = -1; } private boolean isEmpty(String value) { return (value == null || value.trim().equals("")); } // --- Setters public void setVar(String var) { if (isEmpty(var)) this.var = null; else this.var = var; } public void setTopic(String topic) { if (isEmpty(topic)) this.topic = null; else this.topic = topic; } public void setHideAssociations(String hideassocs) { if (isEmpty(hideassocs)) this.hideassocs = null; else this.hideassocs = hideassocs; } public void setExcludeAssociations(String exclassocs) { if (isEmpty(exclassocs)) this.exclassocs = null; else this.exclassocs = exclassocs; } public void setExcludeRoles(String exclroles) { if (isEmpty(exclroles)) this.exclroles = null; else this.exclroles = exclroles; } public void setExcludeTopics(String excltopics) { if (isEmpty(excltopics)) this.excltopics = null; else this.excltopics = excltopics; } public void setIncludeAssociations(String inclassocs) { if (isEmpty(inclassocs)) this.inclassocs = null; else this.inclassocs = inclassocs; } public void setIncludeTopics(String incltopics) { if (isEmpty(incltopics)) this.incltopics = null; else this.incltopics = incltopics; } public void setFilterQuery(String filterQuery) { if (isEmpty(filterQuery)) this.filterQuery = null; else this.filterQuery = filterQuery; } public void setMaxChildren(int maxChildren) { this.maxChildren = maxChildren; } public void setHeadingOrderQuery(String headingOrderQuery) { if (isEmpty(headingOrderQuery)) this.headingOrderQuery = null; else this.headingOrderQuery = headingOrderQuery; } public void setHeadingOrdering(String headingOrdering) { if (headingOrdering != null && headingOrdering.equalsIgnoreCase("desc")) this.headingOrdering = RelatedTopics.ORDERING_DESC; else this.headingOrdering = RelatedTopics.ORDERING_ASC; } public void setChildOrderQuery(String childOrderQuery) { if (isEmpty(childOrderQuery)) this.childOrderQuery = null; else this.childOrderQuery = childOrderQuery; } public void setChildOrdering(String childOrdering) { if (childOrdering != null && childOrdering.equalsIgnoreCase("desc")) this.childOrdering = RelatedTopics.ORDERING_DESC; else this.childOrdering = RelatedTopics.ORDERING_ASC; } public void setAggregateHierarchy(boolean aggregateHierarchy) { this.aggregateHierarchy = aggregateHierarchy; } public void setAggregateAssociations(String aggregateAssociations) { if (isEmpty(aggregateAssociations)) this.aggregateAssociations = null; else this.aggregateAssociations = aggregateAssociations; } // --- Internal private Object getVariableValue(String var) { // first try to access an OKS variable try { Collection coll; ContextTag contextTag = FrameworkUtils.getContextTag(pageContext); if (contextTag != null) { coll = contextTag.getContextManager().getValue(var); // FIXME: what if it's empty? return coll.iterator().next(); } } catch (VariableNotSetException e) { // this is OK; we just move on to trying the page context } return InteractionELSupport.getValue(var, pageContext); } private void buildModel(ContextTag context) { related = new RelatedTopics(); if (context != null) related.setTologContext(context.getDeclarationContext()); related.setWeakAssociationTypes(getUnionOfVariables(hideassocs)); related.setExcludeAssociationTypes(getUnionOfVariables(exclassocs)); related.setExcludeRoleTypes(getUnionOfVariables(exclroles)); related.setExcludeTopicTypes(getUnionOfVariables(excltopics)); related.setIncludeAssociationTypes(getUnionOfVariables(inclassocs)); related.setIncludeTopicTypes(getUnionOfVariables(incltopics)); related.setFilterQuery(filterQuery); related.setMaxChildren(maxChildren); related.setHeadingOrderQuery(headingOrderQuery); related.setHeadingOrdering(headingOrdering); related.setChildOrderQuery(childOrderQuery); related.setChildOrdering(childOrdering); related.setAggregateHierarchy(aggregateHierarchy); related.setAggregateAssociations(getUnionOfVariables(aggregateAssociations)); } private Set getUnionOfVariables(String config) { if (config == null) return null; try { List values = FrameworkUtils.evaluateParameterList(pageContext, config); if (values.isEmpty()) return null; Set result = new CompactHashSet(); for (int i=0; i < values.size(); i++) { Collection v = (Collection)values.get(i); if (v != null) result.addAll(v); } return result; } catch (Throwable t) { throw new OntopiaRuntimeException(t); } } }