/*
* #!
* Ontopia DB2TM
* #-
* 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.db2tm;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.jsp.PageContext;
import net.ontopia.infoset.core.LocatorIF;
import net.ontopia.topicmaps.core.TMObjectIF;
import net.ontopia.topicmaps.core.TopicIF;
import net.ontopia.topicmaps.core.TopicMapIF;
import net.ontopia.utils.StringUtils;
/**
* INTERNAL: Helper class used by DB2TM internals.
*/
public class Utils {
private Utils() {
}
/**
* INTERNAL: Helper method for maintaining a relation mapping
* instance throughout a page context.
*/
public static RelationMapping getRelationMapping(PageContext ctxt) {
RelationMapping db = (RelationMapping)
ctxt.getAttribute("RelationMapping", PageContext.APPLICATION_SCOPE);
if (db == null) {
db = new RelationMapping();
ctxt.setAttribute("RelationMapping", db, PageContext.APPLICATION_SCOPE);
}
return db;
}
/**
* INTERNAL: Returns a map where the keys are data sources and each
* entry is a collection of their individual relations. Before
* returning all relations will be verified against the relations
* declared in the mapping. If relations are missing an error is
* issued indicating which ones are missing.
*/
public static Map<DataSourceIF, Collection<Relation>> verifyRelationsForMapping(RelationMapping rmapping) {
// build return value
Collection<DataSourceIF> ds = rmapping.getDataSources();
Map<DataSourceIF, Collection<Relation>> foundRelations = new HashMap<DataSourceIF, Collection<Relation>>(ds.size());
for (DataSourceIF datasource : ds) {
foundRelations.put(datasource, datasource.getRelations());
}
// detect missing relations
List<Relation> missingRelations = new ArrayList<Relation>();
for (Relation relation : rmapping.getRelations()) {
boolean relationMapped = false;
for (Collection<Relation> frels : foundRelations.values()) {
if (frels.contains(relation)) {
relationMapped = true;
break;
};
}
if (!relationMapped) missingRelations.add(relation);
}
// complain if found mappings without relations
int size = missingRelations.size();
if (size > 1) {
String[] relnames = new String[size];
for (int i=0; i < relnames.length; i++) {
relnames[i] = missingRelations.get(i).getName();
}
throw new DB2TMException("No relations found for mappings: " +
StringUtils.join(relnames, ", "));
} else if (size == 1) {
throw new DB2TMException("No relation found for mapping: " +
missingRelations.get(0).getName());
}
return foundRelations;
}
// ---------------------------------------------------------------------------
// Utility methods
// ---------------------------------------------------------------------------
static TopicIF getTopic(String id, Context ctx) {
// Note: null values or empty strings are considered dead
if (isValueEmpty(id))
return null;
if (id.charAt(0) == '#') {
String entity_id = id.substring(1);
return (TopicIF)ctx.getEntityObjectById(entity_id);
}
TopicMapIF tm = ctx.getTopicMap();
// resolve reference
int loctype;
LocatorIF loc;
int cix = id.indexOf(':');
if (cix >= 1) {
// prefix reference
String prefix_id = id.substring(0, cix);
Prefix prefix = ctx.getMapping().getPrefix(prefix_id);
if (prefix == null)
throw new DB2TMConfigException("Unknown prefix: '" + prefix_id +
"' (value='" + id + "')");
String relloc = prefix.getLocator() + id.substring(cix + 1);
if (ctx.getBaseLocator() == null) {
throw new DB2TMException("Cannot resolve locator '" + relloc + "', missing a base locator");
}
loc = ctx.getBaseLocator().resolveAbsolute(relloc);
loctype = prefix.getType();
} else {
throw new DB2TMConfigException("Illegal prefixed value: '" + id + "'");
}
// look up topic by identifier
switch (loctype) {
case Prefix.TYPE_SUBJECT_IDENTIFIER:
TopicIF topic = tm.getTopicBySubjectIdentifier(loc);
if (topic != null)
return topic;
break;
case Prefix.TYPE_ITEM_IDENTIFIER:
TMObjectIF tmobject = tm.getObjectByItemIdentifier(loc);
if (tmobject != null)
return (TopicIF) tmobject;
break;
case Prefix.TYPE_SUBJECT_LOCATOR:
topic = tm.getTopicBySubjectLocator(loc);
if (topic != null)
return topic;
break;
}
// create new topic
TopicIF newtopic = ctx.getBuilder().makeTopic();
ctx.registerNewObject(newtopic);
// add identity
switch (loctype) {
case Prefix.TYPE_SUBJECT_IDENTIFIER:
newtopic.addSubjectIdentifier(loc);
break;
case Prefix.TYPE_ITEM_IDENTIFIER:
newtopic.addItemIdentifier(loc);
break;
case Prefix.TYPE_SUBJECT_LOCATOR:
newtopic.addSubjectLocator(loc);
break;
}
return newtopic;
}
static String getValue(Relation relation, Entity entity, Field field,
String[] tuple, Context ctx) {
return field.getValue(tuple);
}
static boolean isValueEmpty(String value) {
return (value == null || value.equals(""));
}
static LocatorIF getLocator(Relation relation, Entity entity, Field field,
String[] tuple, Context ctx) {
String value = getValue(relation, entity, field, tuple, ctx);
if (isValueEmpty(value)) return null;
if (ctx.getBaseLocator() == null) {
throw new DB2TMException("Cannot resolve locator '" + value + "', missing a base locator");
}
return ctx.getBaseLocator().resolveAbsolute(value);
}
static String expandPrefixedValue(String value, Context ctx) {
int cix = value.indexOf(':');
if (cix >= 1) {
// prefix reference
String prefix_id = value.substring(0, cix);
Prefix prefix = ctx.getMapping().getPrefix(prefix_id);
if (prefix == null)
throw new DB2TMConfigException("Unknown prefix: '" + prefix_id +
"' (value='" + value + "')");
return prefix.getLocator() + value.substring(cix + 1);
} else {
throw new DB2TMConfigException("Illegal prefixed value: '" + value + "'");
}
}
}