/**
* Copyright (C) 2012-2013 Selventa, Inc.
*
* This file is part of the OpenBEL Framework.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The OpenBEL Framework is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the OpenBEL Framework. If not, see <http://www.gnu.org/licenses/>.
*
* Additional Terms under LGPL v3:
*
* This license does not authorize you and you are prohibited from using the
* name, trademarks, service marks, logos or similar indicia of Selventa, Inc.,
* or, in the discretion of other licensors or authors of the program, the
* name, trademarks, service marks, logos or similar indicia of such authors or
* licensors, in any marketing or advertising materials relating to your
* distribution of the program or any covered product. This restriction does
* not waive or limit your obligation to keep intact all copyright notices set
* forth in the program as delivered to you.
*
* If you distribute the program in whole or in part, or any modified version
* of the program, and you assume contractual liability to the recipient with
* respect to the program or modified version, then you will indemnify the
* authors and licensors of the program for any liabilities that these
* contractual assumptions directly impose on those licensors and authors.
*/
package org.openbel.framework.ws.utils;
import static java.util.Collections.emptyList;
import static org.apache.commons.codec.binary.Base64.decodeBase64;
import static org.apache.commons.codec.binary.Base64.encodeBase64;
import static org.apache.commons.lang.StringUtils.join;
import static org.apache.commons.lang.StringUtils.split;
import static org.openbel.framework.common.BELUtilities.hasItems;
import static org.openbel.framework.common.BELUtilities.noLength;
import static org.openbel.framework.common.enums.CitationType.BOOK;
import static org.openbel.framework.common.enums.CitationType.JOURNAL;
import static org.openbel.framework.common.enums.CitationType.ONLINE_RESOURCE;
import static org.openbel.framework.common.enums.CitationType.OTHER;
import static org.openbel.framework.common.enums.CitationType.PUBMED;
import static org.openbel.framework.ws.model.CitationType.fromValue;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CoderResult;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import org.openbel.framework.api.KamDialect;
import org.openbel.framework.api.KamImpl;
import org.openbel.framework.api.KAMStore;
import org.openbel.framework.api.KAMStoreException;
import org.openbel.framework.api.KamStoreObject;
import org.openbel.framework.api.internal.KAMCatalogDao;
import org.openbel.framework.api.internal.KAMStoreDaoImpl;
import org.openbel.framework.api.internal.KAMCatalogDao.KamInfo;
import org.openbel.framework.api.internal.KAMStoreDaoImpl.BelDocumentInfo;
import org.openbel.framework.api.internal.KAMStoreDaoImpl.KamProtoEdge;
import org.openbel.framework.api.internal.KAMStoreDaoImpl.KamProtoNode;
import org.openbel.framework.api.internal.KAMStoreDaoImpl.TermParameter;
import org.openbel.framework.common.InvalidArgument;
import org.openbel.framework.common.enums.FunctionEnum;
import org.openbel.framework.common.enums.ReturnType;
import org.openbel.framework.common.model.*;
import org.openbel.framework.ws.dialect.BELSyntax;
import org.openbel.framework.ws.model.*;
import org.openbel.framework.ws.model.Annotation;
import org.openbel.framework.ws.model.Citation;
import org.openbel.framework.ws.model.Namespace;
import org.openbel.framework.ws.model.Statement;
/**
* Provides static converter methods to go from KamStore objects to JAXB
* wire-safe objects for return via the SOAP interface TODO Document
*
* @author julianjray
*/
public class Converter {
public static final String FIELD_SEP = "|";
private static final Charset ASCII = Charset.forName("US-ASCII");
private static final GregorianCalendar calendar = new GregorianCalendar();
private static final ObjectFactory OBJECT_FACTORY = ObjectFactorySingleton
.getInstance();
/**
* Converts a {@link KamEdge ws kam edge} to a
* {@link org.openbel.framework.api.Kam.KamEdge kam edge}
* using the {@link org.openbel.framework.api.Kam kam}.
*
* @param kamEdge the {@link KamEdge ws kam edge} to convert from
* @param kam the {@link org.openbel.framework.api.Kam kam}
* to find the kam store kam edge
* @return the {@link org.openbel.framework.api.Kam.KamEdge
* kam edge} to convert to
* @throws InvalidIdException Thrown if the kam edge id is invalid
*/
public static org.openbel.framework.api.Kam.KamEdge
convert(KamEdge kamEdge, org.openbel.framework.api.Kam kam)
throws InvalidIdException {
if (kamEdge == null) {
return null;
}
final KamStoreObjectRef ref = decodeEdge(kamEdge);
int edgeId = ref.getKamStoreObjectId();
return kam.findEdge(edgeId);
}
/**
* @param edgeDirectionType
* @return
*/
public static org.openbel.framework.api.EdgeDirectionType
convert(EdgeDirectionType edgeDirectionType) {
if (null == edgeDirectionType) {
return null;
} else if (edgeDirectionType == EdgeDirectionType.FORWARD) {
return org.openbel.framework.api.EdgeDirectionType.FORWARD;
} else if (edgeDirectionType == EdgeDirectionType.REVERSE) {
return org.openbel.framework.api.EdgeDirectionType.REVERSE;
} else {
return org.openbel.framework.api.EdgeDirectionType.BOTH;
}
}
public static org.openbel.framework.api.EdgeFilter convert(
final org.openbel.framework.api.Kam kam,
final EdgeFilter filter) {
if (filter == null) {
return null;
}
org.openbel.framework.api.EdgeFilter kamEdgeFilter;
kamEdgeFilter = kam.createEdgeFilter();
final List<RelationshipTypeFilterCriteria> criterion;
criterion = filter.getRelationshipCriteria();
for (final RelationshipTypeFilterCriteria criteria : criterion) {
kamEdgeFilter.add(convert(criteria));
}
return kamEdgeFilter;
}
public static org.openbel.framework.api.NodeFilter convert(
final org.openbel.framework.api.Kam kam,
NodeFilter nodeFilter) {
if (null != nodeFilter) {
final org.openbel.framework.api.NodeFilter kamNodeFilter =
kam
.createNodeFilter();
// handle function type criteria
List<FunctionTypeFilterCriteria> ftCriterion = nodeFilter
.getFunctionTypeCriteria();
for (final FunctionTypeFilterCriteria criteria : ftCriterion) {
final org.openbel.framework.api.FunctionTypeFilterCriteria kamNodeCriteria =
new org.openbel.framework.api.FunctionTypeFilterCriteria();
kamNodeCriteria.setInclude(criteria.isIsInclude());
final List<FunctionType> functionTypes = criteria.getValueSet();
for (final FunctionType functionType : functionTypes) {
final org.openbel.framework.common.enums.FunctionEnum kamNodeFunctionType =
convert(functionType);
kamNodeCriteria.add(kamNodeFunctionType);
}
kamNodeFilter.add(kamNodeCriteria);
}
// handle function return type criteria
final List<FunctionReturnTypeFilterCriteria> frtCriterion =
nodeFilter
.getFunctionReturnCriteria();
for (final FunctionReturnTypeFilterCriteria criteria : frtCriterion) {
final org.openbel.framework.api.FunctionReturnFilterCriteria kamNodeCriteria =
new org.openbel.framework.api.FunctionReturnFilterCriteria();
kamNodeCriteria.setInclude(criteria.isIsInclude());
final List<FunctionReturnType> functionReturnTypes =
criteria.getValueSet();
for (final FunctionReturnType functionReturnType : functionReturnTypes) {
final ReturnType kamNodeReturnType =
convert(functionReturnType);
kamNodeCriteria.add(kamNodeReturnType);
}
kamNodeFilter.add(kamNodeCriteria);
}
return kamNodeFilter;
}
return null;
}
/**
* Converts a {@link KamFilter ws KAM filter} into a {@link KAMCatalogDao.KamFilter KAM filter}.
* @param wsFilter
* @param kamInfo
* @return
* @throws InvalidIdException
*/
public static KAMCatalogDao.KamFilter convert(KamFilter wsFilter,
KamInfo kamInfo) throws InvalidIdException {
if (null != wsFilter) {
// create a new one and send it back
KAMCatalogDao.KamFilter ret = kamInfo.createKamFilter();
for (AnnotationFilterCriteria ac : wsFilter.getAnnotationCriteria()) {
ret.add(convert(ac));
}
for (BelDocumentFilterCriteria bc : wsFilter.getDocumentCriteria()) {
ret.add(convert(bc));
}
for (CitationFilterCriteria cc : wsFilter.getCitationCriteria()) {
ret.add(convert(cc));
}
for (RelationshipTypeFilterCriteria rc : wsFilter
.getRelationshipCriteria()) {
ret.add(convert(rc));
}
return ret;
}
return null;
}
/**
* Converts a {@link AnnotationFilterCriteria ws annotation filter criteria} into
* an {@link org.openbel.framework.api.AnnotationFilterCriteria
* annotation filter criteria}.
* @param wsFilterCriteria
* @return
* @throws InvalidIdException
*/
public static
org.openbel.framework.api.AnnotationFilterCriteria
convert(AnnotationFilterCriteria wsFilterCriteria)
throws InvalidIdException {
org.openbel.framework.api.AnnotationFilterCriteria filterCriteria =
new org.openbel.framework.api.AnnotationFilterCriteria(
convert(wsFilterCriteria.getAnnotationType()));
filterCriteria.setInclude(wsFilterCriteria.isIsInclude());
for (String s : wsFilterCriteria.getValueSet()) {
filterCriteria.add(s);
}
return filterCriteria;
}
/**
* Converts a {@link AnnotationType ws annotation type} to an
* {@link KAMStoreDaoImpl.AnnotationType annotation type}.
* @param wsAnnotationType
* @return
* @throws InvalidIdException
*/
public static KAMStoreDaoImpl.AnnotationType convert(
AnnotationType wsAnnotationType) throws InvalidIdException {
String wsId = wsAnnotationType.getId();
String wsName = wsAnnotationType.getName();
String wsDescription = wsAnnotationType.getDescription();
String wsUsage = wsAnnotationType.getUsage();
AnnotationDefinitionType wsAdt =
wsAnnotationType.getAnnotationDefinitionType();
final int id =
KamStoreObjectRef.decode(wsId,
KAMStoreDaoImpl.AnnotationType.class)
.getKamStoreObjectId();
KAMStoreDaoImpl.AnnotationDefinitionType adt = convert(wsAdt);
return new KAMStoreDaoImpl.AnnotationType(id, wsName, wsDescription,
wsUsage, adt);
}
/**
* Converts a {@link AnnotationDefinitionType ws annotation definition type} to a
* {@link KAMStoreDaoImpl.AnnotationDefinitionType annotation definition type}.
* @param wsAdt
* @return
*/
public static KAMStoreDaoImpl.AnnotationDefinitionType convert(
AnnotationDefinitionType wsAdt) {
switch (wsAdt) {
case ENUMERATION:
return KAMStoreDaoImpl.AnnotationDefinitionType.ENUMERATION;
case REGULAR_EXPRESSION:
return KAMStoreDaoImpl.AnnotationDefinitionType.REGULAR_EXPRESSION;
case URL:
return KAMStoreDaoImpl.AnnotationDefinitionType.URL;
}
return null;
}
/**
* Converts a {@link CitationFilterCriteria ws citation filter criteria} into a
* {@link org.openbel.framework.api.CitationFilterCriteria
* citation filter criteria}.
* @param wsFilterCriteria
* @return
* @throws InvalidIdException
*/
public static
org.openbel.framework.api.CitationFilterCriteria
convert(CitationFilterCriteria wsFilterCriteria)
throws InvalidIdException {
org.openbel.framework.api.CitationFilterCriteria objFilterCriteria =
new org.openbel.framework.api.CitationFilterCriteria();
objFilterCriteria.setInclude(wsFilterCriteria.isIsInclude());
for (Citation citation : wsFilterCriteria.getValueSet()) {
objFilterCriteria.add(convert(citation));
}
return objFilterCriteria;
}
/**
* Converts a {@link Citation ws citation} to a {@link KAMStoreDaoImpl.Citation citation}.
*
* @param wsCitation
* @return
*/
public static KAMStoreDaoImpl.Citation convert(Citation wsCitation)
throws InvalidIdException {
String wsId = wsCitation.getId();
String wsName = wsCitation.getName();
CitationType wsCitationType = wsCitation.getCitationType();
String wsComment = wsCitation.getComment();
XMLGregorianCalendar wsPublicationDate =
wsCitation.getPublicationDate();
List<String> wsAuthors = wsCitation.getAuthors();
Integer id = null;
try {
id = Integer.parseInt(wsId);
} catch (NumberFormatException e) {
throw new InvalidIdException(wsId);
}
List<String> authors =
(wsAuthors == null ? new ArrayList<String>() : wsAuthors);
Date publicationDate = (wsPublicationDate != null ?
wsPublicationDate.toGregorianCalendar().getTime() : null);
return new KAMStoreDaoImpl.Citation(
wsName, id.toString(), wsComment, publicationDate, authors,
convert(wsCitationType));
}
/**
* @param filterCriteria
* @return
*/
public static
org.openbel.framework.api.CitationFilterCriteria
convert(NamespaceFilterCriteria filterCriteria) {
org.openbel.framework.api.CitationFilterCriteria objFilterCriteria =
new org.openbel.framework.api.CitationFilterCriteria();
objFilterCriteria.setInclude(filterCriteria.isIsInclude());
for (@SuppressWarnings("unused")
Namespace namespace : filterCriteria.getValueSet()) {
// objFilterCriteria.getValues().add(convert(namespace));
}
return objFilterCriteria;
}
/**
* @param wsFilterCriteria
* @return
*/
public static
org.openbel.framework.api.BelDocumentFilterCriteria
convert(BelDocumentFilterCriteria wsFilterCriteria)
throws InvalidIdException {
org.openbel.framework.api.BelDocumentFilterCriteria objFilterCriteria =
new org.openbel.framework.api.BelDocumentFilterCriteria();
objFilterCriteria.setInclude(wsFilterCriteria.isIsInclude());
for (BelDocument belDocument : wsFilterCriteria.getValueSet()) {
objFilterCriteria.add(convert(belDocument));
}
return objFilterCriteria;
}
/**
* @param wsFilterCriteria
* @return
*/
public static
org.openbel.framework.api.RelationshipTypeFilterCriteria
convert(RelationshipTypeFilterCriteria wsFilterCriteria) {
org.openbel.framework.api.RelationshipTypeFilterCriteria objFilterCriteria =
new org.openbel.framework.api.RelationshipTypeFilterCriteria();
objFilterCriteria.setInclude(wsFilterCriteria.isIsInclude());
for (RelationshipType wsRelationshipType : wsFilterCriteria
.getValueSet()) {
objFilterCriteria.add(convert(wsRelationshipType));
}
return objFilterCriteria;
}
/**
* @param objBelTerm
* @return
*/
public static BelTerm convert(KAMStoreDaoImpl.BelTerm objBelTerm,
final KamInfo kamInfo) {
BelTerm belTerm = OBJECT_FACTORY.createBelTerm();
belTerm.setId(KamStoreObjectRef.encode(kamInfo, objBelTerm));
belTerm.setLabel(objBelTerm.getLabel());
return belTerm;
}
/**
* @param objBelStatement
* @return
*/
public static BelStatement
convert(KAMStoreDaoImpl.BelStatement objBelStatement,
final KamInfo kamInfo) {
BelStatement belStatement = OBJECT_FACTORY.createBelStatement();
belStatement.setDocument(convert(objBelStatement
.getBelDocumentInfo(), kamInfo));
belStatement.setId(KamStoreObjectRef.encode(kamInfo, objBelStatement));
if (null != objBelStatement.getObject()) {
if (objBelStatement.getObject() instanceof KAMStoreDaoImpl.BelTerm) {
belStatement
.setObjectTerm(convert(
(KAMStoreDaoImpl.BelTerm) objBelStatement
.getObject(), kamInfo));
} else if (objBelStatement.getObject() instanceof KAMStoreDaoImpl.BelStatement) {
belStatement
.setObjectStatement(convert(
(KAMStoreDaoImpl.BelStatement) objBelStatement
.getObject(), kamInfo));
}
}
belStatement.setRelationship(convert(objBelStatement
.getRelationshipType()));
belStatement.setSubjectTerm(convert(objBelStatement.getSubject(),
kamInfo));
belStatement.setCitation(convert(objBelStatement.getCitation()));
List<KAMStoreDaoImpl.Annotation> objAnnotations =
objBelStatement.getAnnotationList();
for (KAMStoreDaoImpl.Annotation objAnnotation : objAnnotations) {
belStatement.getAnnotations().add(convert(kamInfo, objAnnotation));
}
return belStatement;
}
/**
* @param statement
* @return
*/
public static Statement
convert(org.openbel.framework.common.model.Statement statement) {
Statement wsStmt = OBJECT_FACTORY.createStatement();
wsStmt.setStatement(statement.toBELShortForm());
AnnotationGroup group = statement.getAnnotationGroup();
if (group != null) {
wsStmt.setCitation(convert(group.getCitation()));
List<org.openbel.framework.common.model.Annotation> annotations = group.getAnnotations();
if (hasItems(annotations)) {
for (org.openbel.framework.common.model.Annotation annotation : annotations) {
wsStmt.getAnnotations().add(convert(annotation));
}
}
}
return wsStmt;
}
public static Citation convert(org.openbel.framework.common.model.Citation citation) {
if (citation == null) return null;
Citation wsCitation = OBJECT_FACTORY.createCitation();
wsCitation.setId(citation.getReference());
if (citation.getType() != null) {
String value = citation.getType().getDisplayValue().toUpperCase().replace(' ', '_');
wsCitation.setCitationType(fromValue(value));
}
if (citation.getName() != null) {
wsCitation.setName(citation.getName());
}
if (citation.getDate() != null) {
try {
GregorianCalendar calendar = new GregorianCalendar();
calendar.setTime(citation.getDate().getTime());
wsCitation.setPublicationDate(DatatypeFactory.newInstance().newXMLGregorianCalendar(calendar));
} catch (DatatypeConfigurationException e) {
// Swallowed
}
}
if (citation.getAuthors() != null) {
wsCitation.getAuthors().addAll(citation.getAuthors());
}
wsCitation.setComment(citation.getComment());
return wsCitation;
}
public static Annotation convert(org.openbel.framework.common.model.Annotation annotation) {
if (annotation == null) return null;
Annotation wsAnnotation = OBJECT_FACTORY.createAnnotation();
AnnotationType wsAnnotationType = OBJECT_FACTORY.createAnnotationType();
AnnotationDefinition def = annotation.getDefinition();
if (def.getId() != null) wsAnnotationType.setName(def.getId());
if (def.getDescription() != null) wsAnnotationType.setDescription(def.getDescription());
if (def.getUsage() != null) wsAnnotationType.setUsage(def.getUsage());
if (def.getType() != null) {
AnnotationDefinitionType ad = AnnotationDefinitionType.fromValue(def.getType().toString());
wsAnnotationType.setAnnotationDefinitionType(ad);
}
wsAnnotation.setAnnotationType(wsAnnotationType);
wsAnnotation.setValue(annotation.getValue());
return wsAnnotation;
}
/**
* @param kam
* @param objAnnotation
* @return
*/
public static org.openbel.framework.ws.model.Annotation convert(
final KamInfo kamInfo,
KAMStoreDaoImpl.Annotation objAnnotation) {
AnnotationType convertedType = convert(
objAnnotation.getAnnotationType(), kamInfo);
org.openbel.framework.ws.model.Annotation annotation =
new org.openbel.framework.ws.model.Annotation();
annotation.setAnnotationType(convertedType);
annotation.setId(KamStoreObjectRef.encode(kamInfo, objAnnotation));
annotation.setValue(objAnnotation.getValue());
return annotation;
}
public static
RelationshipType
convert(final org.openbel.framework.common.enums.RelationshipType relationshipTypeEnum) {
if (relationshipTypeEnum == null) {
return null;
}
return RelationshipType.fromValue(relationshipTypeEnum.name());
}
public static org.openbel.framework.common.enums.RelationshipType
convert(final RelationshipType relationshipTypeEnum) {
if (relationshipTypeEnum == null
|| relationshipTypeEnum == RelationshipType.UNKNOWN) {
return null;
}
return org.openbel.framework.common.enums.RelationshipType
.valueOf(relationshipTypeEnum.name());
}
public static
FunctionType
convert(
final org.openbel.framework.common.enums.FunctionEnum functionEnum) {
if (functionEnum == null) {
return null;
}
return FunctionType.fromValue(functionEnum.name());
}
public static FunctionEnum convert(final FunctionType functionType) {
if (functionType == null) {
return null;
}
return FunctionEnum.valueOf(functionType.name());
}
public static FunctionReturnType convert(final ReturnType returnType) {
if (returnType == null) {
return null;
}
return FunctionReturnType.fromValue(returnType.name());
}
public static ReturnType
convert(final FunctionReturnType functionReturnType) {
if (functionReturnType == null) {
return null;
}
return ReturnType.valueOf(functionReturnType.name());
}
/**
* Converts the KamStore kam node to a {@link KamNode ws kam node}.
*
* @param objKamNode the KamStore kam node to convert, which can be
* {@code null}
* @return the converted {@link KamNode ws kam node} or {@code null} if the
* KamStore kam node was {@code null}
*/
public static KamNode convert(final KamInfo kamInfo,
org.openbel.framework.api.Kam.KamNode objKamNode) {
if (objKamNode == null) {
return null;
}
KamNode kamNode = OBJECT_FACTORY.createKamNode();
kamNode.setFunction(convert(objKamNode.getFunctionType()));
kamNode.setId(KamStoreObjectRef.encode(kamInfo, objKamNode));
kamNode.setLabel(objKamNode.getLabel());
return kamNode;
}
/**
* Converts the KamStore kam edge to a {@link KamEdge ws kam edge}.
*
* @param objKamEdge the KamStore kam edge to convert, which can be
* {@code null}
* @return the converted {@link KamEdge ws kam edge} or {@code null} if the
* KamStore kam edge was {@code null}
*/
public static KamEdge convert(final KamInfo kamInfo,
org.openbel.framework.api.Kam.KamEdge objKamEdge) {
if (objKamEdge == null) {
return null;
}
KamEdge kamEdge = OBJECT_FACTORY.createKamEdge();
kamEdge.setId(KamStoreObjectRef.encode(kamInfo, objKamEdge));
kamEdge.setRelationship(convert(objKamEdge.getRelationshipType()));
kamEdge.setSource(convert(kamInfo, objKamEdge.getSourceNode()));
kamEdge.setTarget(convert(kamInfo, objKamEdge.getTargetNode()));
return kamEdge;
}
/**
* Converts {@link org.openbel.framework.common.enums.CitationType} to
* {@link CitationType}.
*
* @param objCitationType Citation type
* @return {@link CitationType}; may be null
*/
public static
CitationType
convert(
org.openbel.framework.common.enums.CitationType objCitationType) {
if (objCitationType == null) {
return null;
}
switch (objCitationType) {
case BOOK:
return CitationType.BOOK;
case JOURNAL:
return CitationType.JOURNAL;
case ONLINE_RESOURCE:
return CitationType.ONLINE_RESOURCE;
case OTHER:
return CitationType.OTHER;
case PUBMED:
return CitationType.PUBMED;
default:
return null;
}
}
/**
* @param objCitation
* @return
*/
public static Citation
convert(KAMStoreDaoImpl.Citation objCitation) {
Citation citation = OBJECT_FACTORY.createCitation();
citation.setCitationType(convert(objCitation.getCitationType()));
citation.setComment(objCitation.getComment());
citation.setId(objCitation.getId());
citation.setName(objCitation.getName());
Date pubdate = objCitation.getPublicationDate();
if (pubdate != null) {
try {
calendar.setTime(pubdate);
citation.setPublicationDate(DatatypeFactory.newInstance()
.newXMLGregorianCalendar(calendar));
} catch (DatatypeConfigurationException e) {
// Swallowed
}
}
List<String> authors = objCitation.getAuthors();
if (authors != null) {
citation.getAuthors().addAll(authors);
}
return citation;
}
/**
* @param kamInfo
* @return
*/
public static Kam
convert(KAMCatalogDao.KamInfo kamInfo) {
Kam kam = OBJECT_FACTORY.createKam();
try {
kam.setId(KamStoreObjectRef.encode(kamInfo, kamInfo));
kam.setDescription(kamInfo.getKamDbObject().getDescription());
calendar.setTime(kamInfo.getKamDbObject().getLastCompiled());
kam.setLastCompiled(DatatypeFactory.newInstance()
.newXMLGregorianCalendar(calendar));
kam.setName(kamInfo.getKamDbObject().getName());
} catch (DatatypeConfigurationException e) {
// Swallowed
}
return kam;
}
/**
* @param objAnnotationType
* @return
*/
public static AnnotationType
convert(KAMStoreDaoImpl.AnnotationType objAnnotationType,
final KamInfo kamInfo) {
AnnotationType annotationType =
OBJECT_FACTORY.createAnnotationType();
annotationType.setDescription(objAnnotationType.getDescription());
annotationType.setId(KamStoreObjectRef.encode(kamInfo,
objAnnotationType));
annotationType.setName(objAnnotationType.getName());
annotationType.setUsage(objAnnotationType.getUsage());
annotationType.setAnnotationDefinitionType(
AnnotationDefinitionType.valueOf(objAnnotationType
.getAnnotationDefinitionType().toString())
);
return annotationType;
}
/**
* @param objBelDocument
* @return
*/
public static BelDocument convert(KAMStoreDaoImpl.BelDocumentInfo docinfo,
final KamInfo kamInfo) {
BelDocument belDocument = OBJECT_FACTORY.createBelDocument();
String authors = docinfo.getAuthors();
if (authors != null) {
for (final String author : split(authors, FIELD_SEP)) {
belDocument.getAuthors().add(author);
}
}
belDocument.setContactInfo(docinfo.getContactInfo());
belDocument.setCopyright(docinfo.getCopyright());
belDocument.setDescription(docinfo.getDescription());
belDocument.setDisclaimer(docinfo.getDisclaimer());
belDocument.setId(KamStoreObjectRef.encode(kamInfo, docinfo));
belDocument.setLicenseInfo(docinfo.getLicenseInfo());
belDocument.setName(docinfo.getName());
belDocument.setVersion(docinfo.getVersion());
for (KAMStoreDaoImpl.AnnotationType objAnnotationType : docinfo
.getAnnotationTypes()) {
belDocument.getAnnotationTypes().add(
convert(objAnnotationType, kamInfo));
}
for (KAMStoreDaoImpl.Namespace namespace : docinfo
.getNamespaces()) {
belDocument.getNamespaces().add(convert(namespace, kamInfo));
}
return belDocument;
}
public static KAMStoreDaoImpl.BelDocumentInfo convert(BelDocument source)
throws InvalidIdException {
String id = source.getId();
String name = source.getName();
String description = source.getDescription();
String version = source.getVersion();
String copyright = source.getCopyright();
String disclaimer = source.getDisclaimer();
String contactInfo = source.getContactInfo();
String licenseInfo = source.getLicenseInfo();
List<String> authors = source.getAuthors();
int intId =
KamStoreObjectRef.decode(id,
KAMStoreDaoImpl.BelDocumentInfo.class)
.getKamStoreObjectId();
String authorString = null;
if (hasItems(authors)) {
authorString = join(authors, FIELD_SEP);
}
List<KAMStoreDaoImpl.AnnotationType> emptyAnnos = emptyList();
List<KAMStoreDaoImpl.Namespace> emptyNSs = emptyList();
final KAMStoreDaoImpl.BelDocumentInfo ret =
new KAMStoreDaoImpl.BelDocumentInfo(
intId, name, description,
version, copyright, disclaimer, contactInfo,
licenseInfo,
authorString, emptyAnnos, emptyNSs);
return ret;
}
/**
* @param objNamespace
* @return
*/
public static Namespace
convert(KAMStoreDaoImpl.Namespace objNamespace,
final KamInfo kamInfo) {
Namespace namespace = OBJECT_FACTORY.createNamespace();
namespace.setId(KamStoreObjectRef.encode(kamInfo, objNamespace));
namespace.setPrefix(objNamespace.getPrefix());
namespace.setResourceLocation(objNamespace.getResourceLocation());
return namespace;
}
public static KAMStoreDaoImpl.Namespace convert(final Namespace src,
final org.openbel.framework.api.Kam kam,
final KAMStore kAMStore) throws InvalidArgument, KAMStoreException {
if (src == null || src.getResourceLocation() == null) {
return null;
}
return kAMStore.getNamespace(kam, src.getResourceLocation());
}
/**
* Convert a common namespace to a WS namespace. WS namespace will not have
* its ID populated as it is not a {@link KamStoreObject}
*
* @param ns
* @return
*/
public static Namespace convert(
final org.openbel.framework.common.model.Namespace ns) {
Namespace ws = OBJECT_FACTORY.createNamespace();
ws.setPrefix(ns.getPrefix());
ws.setResourceLocation(ns.getResourceLocation());
return ws;
}
/**
* Convert a WS namespace to a common namespace
*
* @param ns
* @return
*/
public static org.openbel.framework.common.model.Namespace convert(
final Namespace ws) {
return new org.openbel.framework.common.model.Namespace(
ws.getPrefix(), ws.getResourceLocation());
}
public static org.openbel.framework.common.enums.CitationType convert(
CitationType c) {
if (c == null) {
return null;
}
switch (c) {
case BOOK:
return BOOK;
case JOURNAL:
return JOURNAL;
case ONLINE_RESOURCE:
return ONLINE_RESOURCE;
case OTHER:
return OTHER;
case PUBMED:
return PUBMED;
default:
return null;
}
}
public static SimplePath convert(
final org.openbel.framework.api.SimplePath simplePath,
final KamInfo kamInfo) {
final SimplePath wsSimplePath = new SimplePath();
wsSimplePath.setSource(convert(kamInfo, simplePath.getSource()));
wsSimplePath.setTarget(convert(kamInfo, simplePath.getTarget()));
for (org.openbel.framework.api.Kam.KamEdge kamEdge : simplePath
.getEdges()) {
wsSimplePath.getEdges().add(convert(kamInfo, kamEdge));
}
return wsSimplePath;
}
public static BELSyntax convert(BelSyntax ws) {
switch (ws) {
case LONG_FORM:
return BELSyntax.LONG_FORM;
case SHORT_FORM:
return BELSyntax.SHORT_FORM;
default:
throw new UnsupportedOperationException("Unsupported syntax: " + ws);
}
}
public static KamStoreObjectRef decodeNode(final KamNode kamNode)
throws InvalidIdException {
return KamStoreObjectRef.decode(kamNode.getId());
}
public static KamStoreObjectRef decodeEdge(final KamEdge kamEdge)
throws InvalidIdException {
return KamStoreObjectRef.decode(kamEdge.getId());
}
public static final class KamStoreObjectRef {
private final int kamInfoId;
private final int kamStoreObjectId;
private final Class<? extends KamStoreObject> kamStoreObjectClass;
private final String encodedString;
private KamStoreObjectRef(final int kamInfoId,
final int kamStoreObjectId,
final Class<? extends KamStoreObject> kamStoreObjectClass,
final String encodedString) {
if (kamStoreObjectId < 1) {
throw new InvalidArgument("kamStoreObjectId", kamStoreObjectId);
}
if (kamStoreObjectClass == null) {
throw new InvalidArgument("kamStoreObjectClass",
kamStoreObjectClass);
}
this.kamInfoId = kamInfoId;
this.kamStoreObjectId = kamStoreObjectId;
this.kamStoreObjectClass = kamStoreObjectClass;
this.encodedString = encodedString;
}
public int getKamInfoId() {
return kamInfoId;
}
public int getKamStoreObjectId() {
return kamStoreObjectId;
}
public Class<? extends KamStoreObject> getKamStoreObjectClass() {
return kamStoreObjectClass;
}
public String getEncodedString() {
return encodedString;
}
/**
* Encodes the KamInfo and a KamStoreObject instance as a fixed-length, identifying string.
* @param kamInfo
* @param obj
* @return
*/
public static String encode(final KamInfo kamInfo,
final KamStoreObject obj) {
if (obj == null) {
return null;
}
final Integer id = obj.getId();
if (id == null) {
return null;
}
byte prefix =
KamStoreObjectType.fromClass(obj.getClass())
.getRepresentation();
return encode(kamInfo.getId().intValue(), id.intValue(), prefix);
}
/**
* Decodes a string that was encoded with {@link encode} back to the id of
* some KamStoreObject.
* @param encoded
* @param expectedClass The class of a subclass of KamStoreObject that will be
* used to verify the type encoded in the {@code encode()}ed string. If expectedClass
* is null then no verification check is performed.
* @return
* @throws InvalidIdException Thrown if {@code encoded} is {@code null} or empty, or
* if there was an error decoding the {@link encode()}ed string.
*/
public static KamStoreObjectRef decode(String encoded,
Class<? extends KamStoreObject> expectedClass)
throws InvalidIdException {
return decode(encoded, KamStoreObjectType.fromClass(expectedClass));
}
/**
* Identical to {@link decode} except that
* @param encoded
* @return
* @throws InvalidIdException
*/
public static KamStoreObjectRef decode(String encoded)
throws InvalidIdException {
return decode(encoded, (KamStoreObjectType) null);
}
/*
* Private encoding and decoding methods:
*/
private static String encode(final int kamInfoId, int id, byte prefix) {
final byte[] unencoded = new byte[8];
Arrays.fill(unencoded, (byte) 0);
ByteBuffer buffer =
ByteBuffer.allocate(8).putInt(kamInfoId).putInt(id);
buffer.flip();
buffer.get(unencoded);
final byte[] encoded = encodeBase64(unencoded);
// Because padding is added for the Base64 encoding, the last byte of encoded
// is actually encoded padding and is always '='. This is of no use so
// truncate that last byte and add the prefix to the beginning of encoded.
shiftRight(encoded);
encoded[0] = prefix;
return new String(encoded, ASCII);
}
private static KamStoreObjectRef decode(String encodedStr,
KamStoreObjectType expected) throws InvalidIdException {
try {
if (noLength(encodedStr)) {
throw new InvalidIdException();
}
final byte[] encoded = encodedStr.getBytes(ASCII);
if (encoded.length != 12) {
throw new InvalidIdException(encodedStr);
}
// The first byte should contain an ASCII character
// representing the type of object whose ID is encoded.
final byte prefix = encoded[0];
final KamStoreObjectType represented =
KamStoreObjectType.fromRepresentation(prefix);
if (represented == null) {
throw new InvalidIdException(encodedStr);
} else if (expected != null && represented != expected) {
throw new InvalidIdException(encodedStr);
}
// Remove the prefix byte and add back the byte of Base64-encoded padding.
shiftLeft(encoded);
encoded[11] = (byte) 0x3d; // '=' in ASCII
final byte[] decoded = decodeBase64(encoded);
if (decoded.length != 8) {
throw new InvalidIdException(encodedStr);
}
ByteBuffer buffer = ByteBuffer.allocate(8).put(decoded);
buffer.flip();
final int kamInfoId = buffer.getInt();
final int kamStoreObjId = buffer.getInt();
return new KamStoreObjectRef(kamInfoId, kamStoreObjId,
represented.getRepresentedClass(), encodedStr);
} catch (IndexOutOfBoundsException e) {
throw new InvalidIdException(encodedStr);
}
}
private static void shiftRight(final byte[] bytes) {
for (int i = bytes.length - 1; i > 0; --i) {
bytes[i] = bytes[i - 1];
}
}
private static void shiftLeft(final byte[] bytes) {
for (int i = 0; i < bytes.length - 1; ++i) {
bytes[i] = bytes[i + 1];
}
}
}
private static enum KamStoreObjectType {
ANNOTATION('M', KAMStoreDaoImpl.Annotation.class),
ANNOTATION_TYPE('A', KAMStoreDaoImpl.AnnotationType.class),
BEL_DOCUMENT_INFO('D', BelDocumentInfo.class),
BEL_STATEMENT('S', KAMStoreDaoImpl.BelStatement.class),
BEL_TERM('T', KAMStoreDaoImpl.BelTerm.class),
KAM_EDGE(
'E',
org.openbel.framework.api.Kam.KamEdge.class),
KAM_NODE(
'N',
org.openbel.framework.api.Kam.KamNode.class),
KAM_PROTO_EDGE('R', KamProtoEdge.class),
KAM_PROTO_NODE('V', KamProtoNode.class),
TERM_PARAMETER('P', TermParameter.class),
KAM_IMPL('K', KamImpl.class),
KAM_INFO('I', KamInfo.class),
NAMESPACE('Q', KAMStoreDaoImpl.Namespace.class),
KAM_DIALECT('X', KamDialect.class);
private static Map<Class<? extends KamStoreObject>, KamStoreObjectType> classesIndex;
private static byte[] representations;
private static int[] repIndex;
static {
final CharsetEncoder asciiEncoder = ASCII.newEncoder();
final KamStoreObjectType[] types = values();
final int n = types.length;
classesIndex =
new HashMap<Class<? extends KamStoreObject>, KamStoreObjectType>(
n);
representations = new byte[n];
for (int i = 0; i < n; ++i) {
final KamStoreObjectType type = types[i];
classesIndex.put(type.clazz, type);
type.repByte = representations[i] =
Converter.encode(asciiEncoder, type.rep).byteValue();
}
repIndex = sortAndCreateIndex(representations);
}
private final Class<? extends KamStoreObject> clazz;
private final char rep;
private byte repByte;
private KamStoreObjectType(final char rep,
final Class<? extends KamStoreObject> clazz) {
this.clazz = clazz;
this.rep = rep;
this.repByte = 0;
}
public static KamStoreObjectType fromClass(
Class<? extends KamStoreObject> clazz) {
KamStoreObjectType ret = classesIndex.get(clazz);
if (ret == null) {
// check interfaces
for (Class<?> i : clazz.getInterfaces()) {
if (KamStoreObject.class.isAssignableFrom(i)) {
ret = classesIndex.get(i);
break;
}
}
}
if (ret == null) {
throw new UnsupportedOperationException(String.format(
"Class '%s' does not have a corresponding %s!",
clazz.getName(),
KamStoreObjectType.class.getSimpleName()));
}
return ret;
}
public static KamStoreObjectType fromRepresentation(final byte rep) {
int j = Arrays.binarySearch(representations, rep);
return (j >= 0 ? values()[repIndex[j]] : null);
}
public byte getRepresentation() {
return repByte;
}
public Class<? extends KamStoreObject> getRepresentedClass() {
return clazz;
}
private static int[] sortAndCreateIndex(final byte[] bytes) {
int n = bytes.length;
int[] index = new int[n];
for (int i = 0; i < n; ++i) {
index[i] = i;
}
for (int i = 0; i < n - 1; ++i) {
for (int j = i + 1; j < n; ++j) {
if (bytes[i] > bytes[j]) {
final byte swap = bytes[i];
final int k = index[i];
bytes[i] = bytes[j];
index[i] = index[j];
bytes[j] = swap;
index[j] = k;
}
}
}
return index;
}
}
private static Byte encode(final CharsetEncoder encoder, final char c) {
encoder.reset();
if (!encoder.canEncode(c)) {
return null;
}
encoder.reset();
ByteBuffer buffer = ByteBuffer.allocate(1);
CharBuffer charBuffer = CharBuffer.allocate(1).put(c);
charBuffer.flip();
CoderResult result = null;
result = encoder.encode(charBuffer, buffer, false);
if (!result.isUnderflow()) {
return null;
}
result = encoder.encode(charBuffer, buffer, true);
if (result.isMalformed() || result.isUnmappable()) {
return null;
}
result = encoder.flush(buffer);
if (!result.isUnderflow()) {
return null;
}
buffer.flip();
return buffer.get(0);
}
}