/*
* #!
* 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.io.IOException;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.JspTagException;
import javax.servlet.jsp.tagext.TagSupport;
import net.ontopia.topicmaps.core.TMObjectIF;
import net.ontopia.topicmaps.core.TopicMapIF;
import net.ontopia.topicmaps.core.index.NameIndexIF;
import net.ontopia.infoset.core.LocatorIF;
import net.ontopia.infoset.impl.basic.URILocator;
import net.ontopia.topicmaps.nav2.core.NavigatorCompileException;
import net.ontopia.topicmaps.nav2.core.NavigatorRuntimeException;
import net.ontopia.topicmaps.nav2.core.ValueAcceptingTagIF;
import net.ontopia.topicmaps.nav2.core.NavigatorPageIF;
import net.ontopia.topicmaps.nav2.utils.NavigatorUtils;
import net.ontopia.topicmaps.nav2.taglibs.value.BaseValueProducingAndAcceptingTag;
import net.ontopia.topicmaps.nav2.taglibs.logic.ContextTag;
import net.ontopia.topicmaps.nav2.utils.FrameworkUtils;
/**
* INTERNAL: Value Producing Tag for looking up objects by their
* <ul>
* <li>subject address,
* <li>subject indicator,
* <li>source locator,
* <li>or object id.
* </ul>
*/
public class LookupTag extends BaseValueProducingAndAcceptingTag {
// constants
public final static String KIND_SUBJECT = "subject";
public final static String KIND_INDICATOR = "indicator";
public final static String KIND_SOURCE = "source";
// tag attributes
private String indicator;
private String subject;
private String source;
private String objectid;
private String parameter;
private String basenameValue;
private String variantValue;
private String lookupAs;
private boolean expect = false; // do not expect result by default
public Collection process(Collection values) throws JspTagException {
// check first if unique attribute settings
int setParams = ((indicator!=null) ? 1 : 0)
+ ((subject!=null) ? 1 : 0)
+ ((source!=null) ? 1 : 0)
+ ((objectid!=null) ? 1 : 0)
+ ((lookupAs!=null) ? 1 : 0)
+ ((parameter!=null) ? 1 : 0)
+ ((basenameValue!=null) ? 1 : 0)
+ ((variantValue!=null) ? 1 : 0);
if (setParams != 1)
throw new NavigatorCompileException("LookupTag: Ambiguous attribute " +
"settings (need 1, got " + setParams + ").");
// try to retrieve default value from ContextManager
ContextTag contextTag = FrameworkUtils.getContextTag(pageContext);
// get topicmap object on which we should compute
TopicMapIF topicmap = contextTag.getTopicMap();
if (topicmap == null)
throw new NavigatorRuntimeException("LookupTag found no topic map.");
// result collection which contains as first entry one topic map object
Collection resColl = new ArrayList();
// try to lookup topic map object
try {
if (lookupAs != null) {
if (values != null && !values.isEmpty()) {
Iterator iter = values.iterator();
while (iter.hasNext()) {
Object locator = iter.next();
if (locator instanceof LocatorIF) {
if (lookupAs.equals(KIND_SUBJECT)) {
resColl.add(topicmap.getTopicBySubjectLocator((LocatorIF)locator));
} else if (lookupAs.equals(KIND_INDICATOR)) {
resColl.add(topicmap.getTopicBySubjectIdentifier((LocatorIF)locator));
} else if (lookupAs.equals(KIND_SOURCE)) {
resColl.add(topicmap.getObjectByItemIdentifier((LocatorIF)locator));
} else {
throw new NavigatorCompileException("LookupTag: Unknown as attribute value:" + lookupAs);
}
}
}
}
} else {
if (indicator != null) {
resColl.add(topicmap.getTopicBySubjectIdentifier(getLocator(topicmap, indicator)));
} else if (subject != null) {
resColl.add(topicmap.getTopicBySubjectLocator(getLocator(topicmap, subject)));
} else if (source != null) {
resColl.add(topicmap.getObjectByItemIdentifier(getLocator(topicmap, source)));
} else if (objectid != null) {
resColl.add(topicmap.getObjectById(objectid));
} else if (parameter != null) {
String id = pageContext.getRequest().getParameter(parameter);
TMObjectIF object = NavigatorUtils.stringID2Object(topicmap, id);
if (object != null)
resColl.add(object);
} else if (basenameValue != null) {
NameIndexIF nameIndex = getNameIndex(topicmap);
// add Collection of TopicNameIF objects
resColl.addAll(nameIndex.getTopicNames(basenameValue));
} else if (variantValue != null) {
NameIndexIF nameIndex = getNameIndex(topicmap);
// add Collection of VariantIF objects
resColl.addAll(nameIndex.getVariants(variantValue));
}
}
} catch (MalformedURLException e) {
throw new NavigatorCompileException("Invalid URI specified in LookupTag.", e);
}
// eventually a null element was added so be sure to remove that
resColl.remove(null);
// complain if a result was expected
if (expect && resColl.isEmpty())
throw new NavigatorRuntimeException("LookupTag expected to find an object, but none was found.");
return resColl;
}
// -----------------------------------------------------------------
// set methods for tag attributes
// -----------------------------------------------------------------
public void setIndicator(String indicator) {
this.indicator = indicator;
}
public void setSubject(String subject) {
this.subject = subject;
}
public void setSource(String source) {
this.source = source;
}
public void setObjectid(String objectid) {
this.objectid = objectid;
}
public void setParameter(String parameter) {
this.parameter = parameter;
}
public void setBasename(String nameValue) {
this.basenameValue = nameValue;
}
public void setVariant(String nameValue) {
this.variantValue = nameValue;
}
public void setExpect(String expect) {
if (expect.equalsIgnoreCase("true") ||
expect.equalsIgnoreCase("yes") )
this.expect = true;
else
this.expect = false;
}
public void setAs(String as) throws NavigatorRuntimeException {
if (!as.equals(KIND_SUBJECT)
&& !as.equals(KIND_INDICATOR)
&& !as.equals(KIND_SOURCE))
throw new NavigatorRuntimeException("Non-supported value ('" + as +
"') given for attribute 'as' in element 'lookup'.");
this.lookupAs = as;
}
// -----------------------------------------------------------------
// internal helper method(s)
// -----------------------------------------------------------------
private NameIndexIF getNameIndex(TopicMapIF topicmap) {
return (NameIndexIF) topicmap
.getIndex("net.ontopia.topicmaps.core.index.NameIndexIF");
}
/**
* INTERNAL: try to convert a URI String to a LocatorIF object,
* check if String is specifying a relative URI.
*/
private LocatorIF getLocator(TopicMapIF topicmap, String locString)
throws MalformedURLException {
LocatorIF base = topicmap.getStore().getBaseAddress();
if (base != null)
return base.resolveAbsolute(locString);
else
return new URILocator(locString);
}
}