/*
* #!
* 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.utils;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.StringTokenizer;
import javax.servlet.ServletContext;
import javax.servlet.jsp.PageContext;
import net.ontopia.infoset.core.LocatorIF;
import net.ontopia.infoset.impl.basic.URILocator;
import net.ontopia.topicmaps.core.TMObjectIF;
import net.ontopia.topicmaps.core.TopicIF;
import net.ontopia.topicmaps.core.TopicMapIF;
import net.ontopia.topicmaps.entry.TopicMapRepositoryIF;
import net.ontopia.topicmaps.nav2.core.NavigatorApplicationIF;
import net.ontopia.topicmaps.nav2.impl.basic.NavigatorApplication;
import net.ontopia.topicmaps.query.core.DeclarationContextIF;
import net.ontopia.topicmaps.query.parser.ParseContextIF;
import net.ontopia.topicmaps.query.parser.QName;
/**
* INTERNAL: A utility class with miscellaneous helper methods used by
* the navigator tag-libraries and the framework.
*/
public final class NavigatorUtils {
/**
* INTERNAL: convert String entries separated by whitespaces
* to a ordered collection.
*
* @param strList delimiter separated list of string entries.
*/
public final static Collection string2Collection(String strList) {
return string2Collection(strList, null);
}
/**
* INTERNAL: convert String entries separated by whitespaces (default)
* to a ordered collection.
*
* @param strList delimiter separated list of string entries.
* @param delimiter characters which are used to separate the list entries.
*/
public final static Collection string2Collection(String strList,
String delimiter) {
Collection list = new ArrayList();
StringTokenizer st;
// check if arguments ok, otherwise return empty collection
if (strList == null || strList.equals(""))
return list;
// setup StringTokenizer
if (delimiter == null)
st = new StringTokenizer(strList);
else
st = new StringTokenizer(strList, delimiter);
// iterate over all tokens and add to list
String str;
while (st.hasMoreTokens()) {
str = st.nextToken();
list.add(str);
}
return list;
}
/**
* INTERNAL: Tries to convert a string which should contain a subject
* identifier, XML ID, or object ID to a <code>TopicIF</code> object
* in the following order:
* <ul>
* <li>try to match a subject indicator (tm.getTopicBySubjectIdentifier)</li>
* <li>try to match a source (tm.getObjectByItemIdentifier)</li>
* <li>try to match a topic id (tm.getObjectById)</li>
* </ul>
*
* @param tm the topic map object
* @param s the String which should be investigated.
* @return A matched topic otherwise null.
*/
public final static TopicIF stringID2Topic(TopicMapIF tm, String s) {
TopicIF t = null;
if (tm == null || s == null || s.equals(""))
return null;
// 1. try to match a subject indicator
try {
t = tm.getTopicBySubjectIdentifier(new URILocator(s));
} catch (MalformedURLException e) {
// apparently not a URL, so try something else
}
// 2. try to match a source
if (t == null) {
try {
LocatorIF uri = tm.getStore().getBaseAddress();
if (uri != null) {
uri = uri.resolveAbsolute("#" + s);
t = (TopicIF) tm.getObjectByItemIdentifier(uri);
}
} catch (ClassCastException e) {
// if it's not a topic, we don't want it
}
}
// 3. try to match a topic id
if (t == null) {
try {
t = (TopicIF) tm.getObjectById(s);
} catch (ClassCastException e) {
// it's ok; we don't want it if it's not a topic
}
}
return t;
}
/**
* INTERNAL: Converts from a string of subject identities, source IDs or
* object IDs separated by spaces (default) to a Collection of topics.
*
* @param tm the topic map
* @param strList separated list of identities and/or ids
* @param delimiter characters which are used to separate the list entries.
* @return A Collection of matched topics in the order they were listed.
* Arguments that do not match will be ignored.
*/
public final static Collection stringIDs2Topics(TopicMapIF tm,
String strList,
String delimiter) {
Collection list = new ArrayList();
StringTokenizer st;
// check if arguments ok, otherwise return empty collection
if (strList == null || tm == null || strList.equals(""))
return list;
// setup StringTokenizer
if (delimiter == null)
st = new StringTokenizer(strList);
else
st = new StringTokenizer(strList, delimiter);
// iterate over all tokens and try to find appropiate topic
String str;
TopicIF topic;
while (st.hasMoreTokens()) {
str = st.nextToken();
topic = stringID2Topic(tm, str);
if (topic != null)
list.add(topic);
}
return list;
}
/**
* INTERNAL: Tries to convert a string which should contain a subject
* identifier, XML ID, or object ID to a <code>TMObjectIF</code>
* object in the following order:
* <ul>
* <li>try to match a subject indicator (tm.getTopicBySubjectIdentifier)</li>
* <li>try to match a source locator (tm.getObjectByItemIdentifier)</li>
* <li>try to match a topic id (tm.getObjectById)</li>
* </ul>
*
* @param tm the topic map object
* @param s the String which should be investigated.
* @return A matched object, or null.
*/
public final static TMObjectIF stringID2Object(TopicMapIF tm, String s) {
return stringID2Object(tm, s, null);
}
/**
* INTERNAL: Tries to convert a string which should contain a subject
* identifier, XML ID, or object ID to a <code>TMObjectIF</code>
* object in the following order:
* <ul>
* <li>try to match a subject indicator (tm.getTopicBySubjectIdentifier)</li>
* <li>try to match a source locator (tm.getObjectByItemIdentifier)</li>
* <li>try to match a topic id (tm.getObjectById)</li>
* <li>try to match a subject identifier with a prefix defined in the DeclarationContextIF</li>
* </ul>
*
* @param tm the topic map object
* @param s the String which should be investigated.
* @param context the context to lookup the prefix in
* @return A matched object, or null.
*/
public final static TMObjectIF stringID2Object(TopicMapIF tm, String s, DeclarationContextIF context) {
TMObjectIF t = null;
if (tm == null || s == null || s.equals(""))
return null;
// 1. try to match a subject indicator
try {
t = tm.getTopicBySubjectIdentifier(new URILocator(s));
} catch (MalformedURLException e) {
// apparently not a URL, so try something else
}
// 2. try to match a source
if (t == null) {
LocatorIF uri = tm.getStore().getBaseAddress();
if (uri != null) {
uri = uri.resolveAbsolute("#" + s);
t = tm.getObjectByItemIdentifier(uri);
}
}
// 3. try to match a topic id
if (t == null)
t = tm.getObjectById(s);
// 4. try to match a prefixed subject identifier
if ((t == null) && (context != null)) {
try {
ParseContextIF pc = (ParseContextIF) context;
t = pc.getObject(new QName(s));
} catch (Exception e) {
// not found, ignore
}
}
return t;
}
/**
* INTERNAL: Gets the topic map repository used by the web application.
*
* @since 3.1
*/
public final static TopicMapRepositoryIF getTopicMapRepository(PageContext pageContext) {
return getNavigatorApplication(pageContext.getServletContext()).getTopicMapRepository();
}
/**
* INTERNAL: Gets the topic map repository used by the web application.
*
* @since 3.1
*/
public final static TopicMapRepositoryIF getTopicMapRepository(ServletContext servletContext) {
return getNavigatorApplication(servletContext).getTopicMapRepository();
}
/**
* INTERNAL: Gets the navigator application instance belonging to
* the web application.
*/
public final static NavigatorApplicationIF getNavigatorApplication(PageContext pageContext) {
return getNavigatorApplication(pageContext.getServletContext());
}
/**
* INTERNAL: Gets the navigator application instance belonging to
* the web application.
*/
public final static NavigatorApplicationIF getNavigatorApplication(ServletContext servletContext) {
NavigatorApplicationIF navApp = (NavigatorApplicationIF)
servletContext.getAttribute(NavigatorApplicationIF.NAV_APP_KEY);
// If there is no current navigator application we need to create one.
if (navApp == null) {
// Initialise new configuration and register it with application context
navApp = new NavigatorApplication(servletContext);
servletContext.setAttribute(NavigatorApplicationIF.NAV_APP_KEY, navApp);
servletContext.log("Setup navigator configuration and " +
"assigned it to application context.");
}
return navApp;
}
/**
* INTERNAL: Returns a stable identifier for the topic map object.
* This will either be the fragment of a source locator, or the
* object ID if no suitable source locator is found.
*/
public static String getStableId(TMObjectIF object) {
if (!object.getItemIdentifiers().isEmpty()) {
LocatorIF base = object.getTopicMap().getStore().getBaseAddress();
if (base != null && base.getNotation().equals("URI")) {
String basestr = base.getAddress() + "#";
Iterator it = object.getItemIdentifiers().iterator();
while (it.hasNext()) {
LocatorIF loc = (LocatorIF) it.next();
String locstr = loc.getAddress();
if (locstr.startsWith(basestr))
return locstr.substring(basestr.length());
}
}
}
return object.getObjectId();
}
}