/* * #! * 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.logic; import java.util.Arrays; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; import javax.servlet.jsp.tagext.TagSupport; import net.ontopia.infoset.impl.basic.URILocator; import net.ontopia.topicmaps.core.TopicIF; import net.ontopia.topicmaps.core.TopicMapIF; import net.ontopia.topicmaps.utils.TopicComparators; import net.ontopia.topicmaps.utils.TopicStringifiers; import net.ontopia.topicmaps.utils.PSI; import net.ontopia.topicmaps.nav.context.UserFilterContextStore; import net.ontopia.topicmaps.nav.utils.comparators.TopicComparator; import net.ontopia.topicmaps.nav2.core.ContextManagerIF; import net.ontopia.topicmaps.nav2.core.NavigatorConfigurationIF; import net.ontopia.topicmaps.nav2.core.NavigatorRuntimeException; import net.ontopia.topicmaps.nav2.core.UserIF; import net.ontopia.topicmaps.nav2.core.ValueAcceptingTagIF; import net.ontopia.topicmaps.nav2.utils.FrameworkUtils; import net.ontopia.utils.StringifierIF; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * INTERNAL: Logic Tag for establishing the outermost * lexical scope in which computation happens. */ public class SetTag extends TagSupport implements ValueAcceptingTagIF { // initialization of logging facility private static Logger log = LoggerFactory.getLogger(SetTag.class.getName()); // constants private static final StringifierIF DEF_TOPIC_STRINGIFIER = TopicStringifiers .getSortNameStringifier(); private static final Comparator DEF_TOPIC_COMPARATOR = TopicComparators .getCaseInsensitiveComparator(DEF_TOPIC_STRINGIFIER); private static final URILocator SORT_LOCATOR = PSI.getXTMSort(); // members private ContextTag contextTag; private Object currentScope; private Collection value; // the value set by the child // tag attributes private String variableName; private Comparator listComparator; private boolean sortItems = true; /** * Process the start tag for this instance. */ public int doStartTag() { this.contextTag = FrameworkUtils.getContextTag(pageContext); this.currentScope = contextTag.getContextManager().getCurrentScope(); this.value = Collections.EMPTY_SET; return EVAL_BODY_INCLUDE; } /** * Process the end tag. */ public int doEndTag() { // Called when we hit the end tag, so that even if the tag has no // content we will still get a value. That is, it is no longer // necessary to call accept() in order to set the variable. // DEFAULT: sorting of elements in collection if (sortItems && value.size() > 1) { Object[] items = value.toArray(); Comparator c = null; try { // --- sort the items c = getComparator(); Arrays.sort(items, c); } catch (Exception e) { log.info("Sorting the list '" + variableName + "' with comparator " + c + " raised an exception: " + e); } // update the value variable so that it points to the sorted list. this.value = Arrays.asList(items); } // bind variable to name in current scope ContextManagerIF ctxtMgr = contextTag.getContextManager(); ctxtMgr.setValueInScope(currentScope, variableName, value); //log.debug("set '" + variableName +"' (" + items + ") to context."); // reset members this.contextTag = null; this.currentScope = null; this.value = null; return EVAL_PAGE; } /** * reset the state of the Tag. */ public void release() { // overwrite default behaviour // do not set parent to null!!! } // ----------------------------------------------------------------- // Set methods for tag attributes // ----------------------------------------------------------------- public void setName(String name) { this.variableName = name; } public void setComparator(String classname) throws NavigatorRuntimeException { if (classname.equalsIgnoreCase("off")) { listComparator = null; sortItems = false; } else { sortItems = true; // NOTE: we're looking up the context tag here because the doStartTag will not have been called yet. if (contextTag == null) this.contextTag = FrameworkUtils.getContextTag(pageContext); listComparator = getComparatorInstance(classname); } } // ----------------------------------------------------------------- // ValueAcceptingTagIF implementation // ----------------------------------------------------------------- public void accept(Collection value) { this.value = value; } private List getTopicNameContext() throws NavigatorRuntimeException { UserIF user = FrameworkUtils.getUser(pageContext); UserFilterContextStore filterContext = user.getFilterContext(); if (filterContext == null) { return Collections.EMPTY_LIST; } else{ TopicMapIF topicmap = contextTag.getTopicMap(); if (topicmap == null) throw new NavigatorRuntimeException("SetTag found no topic map."); return new ArrayList(filterContext.getScopeTopicNames(topicmap)); } } // --- internal helper method protected Comparator getComparator() throws Exception { // use default comparator if setting not overwritten by attribute if (listComparator != null) return listComparator; String defaultComparatorClassName = contextTag.getNavigatorConfiguration() .getProperty(NavigatorConfigurationIF.DEF_COMPARATOR, NavigatorConfigurationIF.DEFVAL_COMPARATOR); // defaultComparator == TopicComparator if (defaultComparatorClassName .equals(NavigatorConfigurationIF.DEFVAL_COMPARATOR)) { TopicMapIF topicmap = contextTag.getTopicMap(); if (topicmap == null) throw new NavigatorRuntimeException("SetTag found no topic map."); TopicIF sortTopic = topicmap.getTopicBySubjectIdentifier( SORT_LOCATOR ); if (sortTopic != null) { // add base name themes that are in user context filter listComparator = new TopicComparator(getTopicNameContext(), Collections.singleton(sortTopic)); } else { List bc = getTopicNameContext(); if (bc.isEmpty()) listComparator = DEF_TOPIC_COMPARATOR; else listComparator = new TopicComparator(bc, Collections.EMPTY_LIST); } } else { listComparator = getComparatorInstance(defaultComparatorClassName); } return listComparator; } protected Comparator getComparatorInstance(String classname) throws NavigatorRuntimeException { if (contextTag == null) return null; Object obj = contextTag.getNavigatorApplication().getInstanceOf(classname); if (obj != null && obj instanceof Comparator) return (Comparator) obj; else return null; } }