Skip to content
Snippets Groups Projects
Commit b74c06fe authored by gmantele's avatar gmantele
Browse files

[TAP] Remove TAPTypes and create a new class to represent a TAP column type:...

[TAP] Remove TAPTypes and create a new class to represent a TAP column type: TAPType. + Improve the conversion between VOTable type and TAP type by embedding it in TAPType. + Modify TAPColumn in order to integrate TAPType and that its VotType is just a conversion of a TAPType. {This commit is not compilable.}
parent 60284e9b
No related branches found
No related tags found
No related merge requests found
...@@ -22,6 +22,7 @@ package tap.metadata; ...@@ -22,6 +22,7 @@ package tap.metadata;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import tap.metadata.TAPType.TAPDatatype;
import adql.db.DBColumn; import adql.db.DBColumn;
import adql.db.DBTable; import adql.db.DBTable;
...@@ -41,11 +42,9 @@ public class TAPColumn implements DBColumn { ...@@ -41,11 +42,9 @@ public class TAPColumn implements DBColumn {
private String utype = null; private String utype = null;
private String datatype = null; private TAPType datatype = new TAPType(TAPDatatype.VARCHAR);
private int size = TAPTypes.NO_SIZE; private VotType votType = datatype.toVotType();
private VotType votType = null;
private boolean principal = false; private boolean principal = false;
...@@ -67,21 +66,25 @@ public class TAPColumn implements DBColumn { ...@@ -67,21 +66,25 @@ public class TAPColumn implements DBColumn {
dbName = adqlName; dbName = adqlName;
lstTargets = new ArrayList<TAPForeignKey>(1); lstTargets = new ArrayList<TAPForeignKey>(1);
lstSources = new ArrayList<TAPForeignKey>(1); lstSources = new ArrayList<TAPForeignKey>(1);
setDefaultType();
} }
public TAPColumn(String columnName, String description){ public TAPColumn(String columnName, TAPType type){
this(columnName); this(columnName);
setDatatype(type);
}
public TAPColumn(String columnName, TAPType type, String description){
this(columnName, type);
this.description = description; this.description = description;
} }
public TAPColumn(String columnName, String description, String unit){ public TAPColumn(String columnName, TAPType type, String description, String unit){
this(columnName, description); this(columnName, type, description);
this.unit = unit; this.unit = unit;
} }
public TAPColumn(String columnName, String description, String unit, String ucd, String utype){ public TAPColumn(String columnName, TAPType type, String description, String unit, String ucd, String utype){
this(columnName, description, unit); this(columnName, type, description, unit);
this.ucd = ucd; this.ucd = ucd;
this.utype = utype; this.utype = utype;
} }
...@@ -111,6 +114,7 @@ public class TAPColumn implements DBColumn { ...@@ -111,6 +114,7 @@ public class TAPColumn implements DBColumn {
/** /**
* @return The table. * @return The table.
*/ */
@Override
public final DBTable getTable(){ public final DBTable getTable(){
return table; return table;
} }
...@@ -181,79 +185,25 @@ public class TAPColumn implements DBColumn { ...@@ -181,79 +185,25 @@ public class TAPColumn implements DBColumn {
/** /**
* @return The datatype. * @return The datatype.
*/ */
public final String getDatatype(){ public final TAPType getDatatype(){
return datatype; return datatype;
} }
/** /**
* @return Array size (>0 or 2 special values: {@link TAPTypes#NO_SIZE} and {@link TAPTypes#STAR_SIZE}). * @param type The new column datatype.
*/
public final int getArraySize(){
return size;
}
/**
* <p>Sets the DB datatype, the size and uses these information to set the corresponding VOTable type.</p>
* <b>Important:</b>
* <ul>
* <li>If the given datatype is not known according to {@link TAPTypes#getDBType(String)}, the datatype of this column is set to its default value (see {@link #setDefaultType()}),</li>
* <li>The VOTable type is set automatically thanks to {@link TAPTypes#getVotType(String, int)}.</li>
* </ul>
*
* @param datatype The datatype to set.
* @param size Array size (>0 or 2 special values: {@link TAPTypes#NO_SIZE} and {@link TAPTypes#STAR_SIZE}).
*
* @see TAPTypes#getDBType(VotType)
* @see TAPTypes#getVotType(String, int)
* @see #setDefaultType()
*/ */
public final void setDatatype(String datatype, int size){ public final void setDatatype(final TAPType type){
this.datatype = TAPTypes.getDBType(datatype); datatype = type;
this.size = (size <= 0 && size != TAPTypes.STAR_SIZE) ? TAPTypes.NO_SIZE : size; votType = datatype.toVotType();
if (this.datatype == null)
setDefaultType();
else
this.votType = TAPTypes.getVotType(this.datatype, this.size);
} }
/** /**
* @return The VOTable type to use. * @return The votType.
*/ */
public final VotType getVotType(){ public final VotType getVotType(){
return votType; return votType;
} }
/**
* <p>Sets the VOTable type and uses it to set the DB datatype and its size.</p>
* <b>Important:</b>
* <ul>
* <li>If the given VOTable type is not known according to {@link TAPTypes#getDBType(VotType)}, the DB datatype of this column and its size are set to the default value (see {@link #setDefaultType()}).</li>
* </ul>
*
* @param type A full VOTable type (that's to say: <code>datatype</code>, <code>arraysize</code> and <code>xtype</code>).
*
* @see TAPTypes#getDBType(VotType)
* @see #setDefaultType()
*/
public final void setVotType(final VotType type){
this.votType = type;
this.datatype = TAPTypes.getDBType(type);
this.size = type.arraysize;
if (this.datatype == null)
setDefaultType();
}
/**
* Sets the default DB datatype (VARCHAR) and its corresponding VOTable type (char , *).
*/
protected final void setDefaultType(){
datatype = TAPTypes.VARCHAR;
size = TAPTypes.STAR_SIZE;
votType = TAPTypes.getVotType(datatype, size);
}
/** /**
* @return The principal. * @return The principal.
*/ */
...@@ -346,12 +296,12 @@ public class TAPColumn implements DBColumn { ...@@ -346,12 +296,12 @@ public class TAPColumn implements DBColumn {
lstSources.clear(); lstSources.clear();
} }
@Override
public DBColumn copy(final String dbName, final String adqlName, final DBTable dbTable){ public DBColumn copy(final String dbName, final String adqlName, final DBTable dbTable){
TAPColumn copy = new TAPColumn((adqlName == null) ? this.adqlName : adqlName, description, unit, ucd, utype); TAPColumn copy = new TAPColumn((adqlName == null) ? this.adqlName : adqlName, datatype, description, unit, ucd, utype);
copy.setDBName((dbName == null) ? this.dbName : dbName); copy.setDBName((dbName == null) ? this.dbName : dbName);
copy.setTable(dbTable); copy.setTable(dbTable);
copy.setDatatype(datatype, size);
copy.setIndexed(indexed); copy.setIndexed(indexed);
copy.setPrincipal(principal); copy.setPrincipal(principal);
copy.setStd(std); copy.setStd(std);
...@@ -361,10 +311,9 @@ public class TAPColumn implements DBColumn { ...@@ -361,10 +311,9 @@ public class TAPColumn implements DBColumn {
} }
public DBColumn copy(){ public DBColumn copy(){
TAPColumn copy = new TAPColumn(adqlName, description, unit, ucd, utype); TAPColumn copy = new TAPColumn(adqlName, datatype, description, unit, ucd, utype);
copy.setDBName(dbName); copy.setDBName(dbName);
copy.setTable(table); copy.setTable(table);
copy.setDatatype(datatype, size);
copy.setIndexed(indexed); copy.setIndexed(indexed);
copy.setPrincipal(principal); copy.setPrincipal(principal);
copy.setStd(std); copy.setStd(std);
......
...@@ -21,7 +21,6 @@ package tap.metadata; ...@@ -21,7 +21,6 @@ package tap.metadata;
import java.io.IOException; import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
...@@ -30,14 +29,13 @@ import java.util.NoSuchElementException; ...@@ -30,14 +29,13 @@ import java.util.NoSuchElementException;
import javax.servlet.ServletConfig; import javax.servlet.ServletConfig;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import adql.db.DBTable;
import tap.resource.Capabilities; import tap.resource.Capabilities;
import tap.resource.TAPResource; import tap.resource.TAPResource;
import tap.resource.VOSIResource; import tap.resource.VOSIResource;
import adql.db.DBTable;
public class TAPMetadata implements Iterable<TAPSchema>, VOSIResource, TAPResource { public class TAPMetadata implements Iterable<TAPSchema>, VOSIResource, TAPResource {
...@@ -314,13 +312,13 @@ public class TAPMetadata implements Iterable<TAPSchema>, VOSIResource, TAPResour ...@@ -314,13 +312,13 @@ public class TAPMetadata implements Iterable<TAPSchema>, VOSIResource, TAPResour
if (c.getDatatype() != null){ if (c.getDatatype() != null){
writer.print(prefix); writer.print(prefix);
writer.print("<dataType xsi:type=\"vod:TAPType\""); writer.print("<dataType xsi:type=\"vod:TAPType\"");
if (c.getArraySize() >= 0){ if (c.getDatatype().length > 0){
writer.print(" size=\""); writer.print(" size=\"");
writer.print(c.getArraySize()); writer.print(c.getDatatype().length);
writer.print("\""); writer.print("\"");
} }
writer.print('>'); writer.print('>');
writer.print(c.getDatatype().toUpperCase()); writer.print(c.getDatatype().type.toString().toUpperCase());
writer.println("</dataType>"); writer.println("</dataType>");
} }
......
...@@ -199,34 +199,20 @@ public class TAPTable implements DBTable { ...@@ -199,34 +199,20 @@ public class TAPTable implements DBTable {
return c; return c;
} }
public TAPColumn addColumn(String columnName, String description, String unit, String ucd, String utype){ public TAPColumn addColumn(String columnName, TAPType datatype, String description, String unit, String ucd, String utype){
if (columnName == null) if (columnName == null)
return null; return null;
TAPColumn c = new TAPColumn(columnName, description, unit, ucd, utype); TAPColumn c = new TAPColumn(columnName, datatype, description, unit, ucd, utype);
addColumn(c); addColumn(c);
return c; return c;
} }
public TAPColumn addColumn(String columnName, String description, String unit, String ucd, String utype, String datatype, int size, boolean principal, boolean indexed, boolean std){ public TAPColumn addColumn(String columnName, TAPType datatype, String description, String unit, String ucd, String utype, boolean principal, boolean indexed, boolean std){
if (columnName == null) if (columnName == null)
return null; return null;
TAPColumn c = new TAPColumn(columnName, description, unit, ucd, utype); TAPColumn c = new TAPColumn(columnName, datatype, description, unit, ucd, utype);
c.setDatatype(datatype, size);
c.setPrincipal(principal);
c.setIndexed(indexed);
c.setStd(std);
addColumn(c);
return c;
}
public TAPColumn addColumn(String columnName, String description, String unit, String ucd, String utype, VotType votType, boolean principal, boolean indexed, boolean std){
if (columnName == null)
return null;
TAPColumn c = new TAPColumn(columnName, description, unit, ucd, utype);
c.setVotType(votType);
c.setPrincipal(principal); c.setPrincipal(principal);
c.setIndexed(indexed); c.setIndexed(indexed);
c.setStd(std); c.setStd(std);
...@@ -482,6 +468,7 @@ public class TAPTable implements DBTable { ...@@ -482,6 +468,7 @@ public class TAPTable implements DBTable {
} }
} }
@Override
public DBTable copy(final String dbName, final String adqlName){ public DBTable copy(final String dbName, final String adqlName){
TAPTable copy = new TAPTable((adqlName == null) ? this.adqlName : adqlName); TAPTable copy = new TAPTable((adqlName == null) ? this.adqlName : adqlName);
copy.setDBName((dbName == null) ? this.dbName : dbName); copy.setDBName((dbName == null) ? this.dbName : dbName);
......
package tap.metadata;
/*
* This file is part of TAPLibrary.
*
* TAPLibrary 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.
*
* TAPLibrary 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 TAPLibrary. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2014 - Astronomishes Rechen Institute (ARI)
*/
import tap.metadata.VotType.VotDatatype;
/**
*
* <p>
* Describe a full TAP column type as it is described in the IVOA document.
* Thus, this object contains 2 attributes: <code>type</code> (or datatype) and <code>length</code> (or size).
* </p>
*
* <p>The length/size may be not defined ; in this case, its value is set to {@link #NO_LENGTH} or is negative or null.</p>
*
* <p>All datatypes declared in the IVOA recommendation document of TAP are listed in an enumeration type: {@link TAPDatatype}.
* It is used to set the attribute type/datatype of this class.</p>
*
* @author Gr&eacute;gory Mantelet (ARI) - gmantele@ari.uni-heidelberg.de
* @version 2.0 (06/2014)
* @since 2.0
*/
public class TAPType {
/**
* List of all datatypes declared in the IVOA recommendation of TAP (in the section UPLOAD).
*
* @author Gr&eacute;gory Mantelet (ARI) - gmantele@ari.uni-heidelberg.de
* @version 2.0 (06/2014)
* @since 2.0
*/
public static enum TAPDatatype{
SMALLINT, INTEGER, BIGINT, REAL, DOUBLE, BINARY, VARBINARY, CHAR, VARCHAR, BLOB, CLOB, TIMESTAMP, POINT, REGION;
}
/** Special value in case no length/size is specified. */
public static final int NO_LENGTH = -1;
/** Datatype of a column. */
public final TAPDatatype type;
/** The length parameter (only few datatypes need this parameter: char, varchar, binary and varbinary). */
public final int length;
/**
* Build a TAP column type by specifying a datatype.
*
* @param datatype Column datatype.
*/
public TAPType(final TAPDatatype datatype){
this(datatype, NO_LENGTH);
}
/**
* Build a TAP column type by specifying a datatype and a length (needed only for datatypes like char, varchar, binary and varbinary).
*
* @param datatype Column datatype.
* @param length Length of the column value (needed only for datatypes like char, varchar, binary and varbinary).
*/
public TAPType(final TAPDatatype datatype, final int length){
if (datatype == null)
throw new NullPointerException("Missing TAP column datatype !");
this.type = datatype;
this.length = length;
}
/**
* Convert this TAP column type into a VOTable field type.
*
* @return The corresponding VOTable field type.
*
* @see #convertIntoVotType(TAPType)
*/
public VotType toVotType(){
return convertIntoVotType(this);
}
@Override
public String toString(){
if (length > 0)
return type + "(" + length + ")";
else
return type.toString();
}
/**
* Convert the given TAP column type into a VOTable field type.
*
* @param taptype The TAP column type to convert.
*
* @return The corresponding VOTable field type.
*/
public static VotType convertIntoVotType(final TAPType taptype){
VotType vot = new VotType(VotDatatype.CHAR, VotType.NO_SIZE, false);
switch(taptype.type){
case SMALLINT:
vot = new VotType(VotDatatype.SHORT, 1, false);
break;
case INTEGER:
vot = new VotType(VotDatatype.INT, 1, false);
break;
case BIGINT:
vot = new VotType(VotDatatype.LONG, 1, false);
break;
case REAL:
vot = new VotType(VotDatatype.FLOAT, 1, false);
break;
case DOUBLE:
vot = new VotType(VotDatatype.DOUBLE, 1, false);
break;
case CHAR:
vot = new VotType(VotDatatype.CHAR, (taptype.length > 0 ? taptype.length : 1), false);
break;
case BINARY:
vot = new VotType(VotDatatype.UNSIGNED_BYTE, (taptype.length > 0 ? taptype.length : VotType.NO_SIZE), false);
break;
case VARBINARY:
vot = new VotType(VotDatatype.UNSIGNED_BYTE, (taptype.length > 0 ? taptype.length : VotType.NO_SIZE), (taptype.length > 0));
break;
case BLOB:
vot = new VotType(VotDatatype.UNSIGNED_BYTE, VotType.NO_SIZE, true, VotType.XTYPE_BLOB);
break;
case CLOB:
vot = new VotType(VotDatatype.CHAR, VotType.NO_SIZE, true, VotType.XTYPE_CLOB);
break;
case TIMESTAMP:
vot = new VotType(VotDatatype.CHAR, VotType.NO_SIZE, true, VotType.XTYPE_TIMESTAMP);
break;
case POINT:
vot = new VotType(VotDatatype.CHAR, VotType.NO_SIZE, true, VotType.XTYPE_POINT);
break;
case REGION:
vot = new VotType(VotDatatype.CHAR, VotType.NO_SIZE, true, VotType.XTYPE_REGION);
break;
case VARCHAR:
default:
vot = new VotType(VotDatatype.CHAR, (taptype.length > 0 ? taptype.length : VotType.NO_SIZE), (taptype.length > 0), null);
break;
}
return vot;
}
/**
* Convert the given VOTable field type into a TAP column type.
*
* @param vottype The VOTable field type to convert.
*
* @return The corresponding TAP column type.
*/
public static TAPType convertFromVotType(final VotType vottype){
if (vottype == null)
return new TAPType(TAPDatatype.VARCHAR);
switch(vottype.datatype){
case SHORT:
case BOOLEAN:
if ((vottype.arraysize <= 1 || vottype.arraysize == VotType.NO_SIZE) && !vottype.unlimitedArraysize)
return new TAPType(TAPDatatype.SMALLINT);
else
return new TAPType(TAPDatatype.VARBINARY);
case INT:
if ((vottype.arraysize <= 1 || vottype.arraysize == VotType.NO_SIZE) && !vottype.unlimitedArraysize)
return new TAPType(TAPDatatype.INTEGER);
else
return new TAPType(TAPDatatype.VARBINARY);
case LONG:
if ((vottype.arraysize <= 1 || vottype.arraysize == VotType.NO_SIZE) && !vottype.unlimitedArraysize)
return new TAPType(TAPDatatype.BIGINT);
else
return new TAPType(TAPDatatype.VARBINARY);
case FLOAT:
if ((vottype.arraysize <= 1 || vottype.arraysize == VotType.NO_SIZE) && !vottype.unlimitedArraysize)
return new TAPType(TAPDatatype.REAL);
else
return new TAPType(TAPDatatype.VARBINARY);
case DOUBLE:
if ((vottype.arraysize <= 1 || vottype.arraysize == VotType.NO_SIZE) && !vottype.unlimitedArraysize)
return new TAPType(TAPDatatype.DOUBLE);
else
return new TAPType(TAPDatatype.VARBINARY);
case UNSIGNED_BYTE:
if (vottype.arraysize > 0){
if (vottype.unlimitedArraysize)
return new TAPType(TAPDatatype.VARBINARY, vottype.arraysize);
else
return new TAPType(TAPDatatype.BINARY, vottype.arraysize);
}else
return new TAPType(TAPDatatype.VARBINARY);
case CHAR:
default:
TAPType taptype = null;
if (vottype.xtype != null && vottype.xtype.trim().length() > 0){
if (vottype.xtype.equalsIgnoreCase(VotType.XTYPE_BLOB))
taptype = new TAPType(TAPDatatype.BLOB);
else if (vottype.xtype.equalsIgnoreCase(VotType.XTYPE_CLOB))
taptype = new TAPType(TAPDatatype.CLOB);
else if (vottype.xtype.equalsIgnoreCase(VotType.XTYPE_TIMESTAMP))
taptype = new TAPType(TAPDatatype.TIMESTAMP);
else if (vottype.xtype.equalsIgnoreCase(VotType.XTYPE_POINT))
taptype = new TAPType(TAPDatatype.POINT);
else if (vottype.xtype.equalsIgnoreCase(VotType.XTYPE_REGION))
taptype = new TAPType(TAPDatatype.REGION);
}
if (taptype == null){
if (vottype.unlimitedArraysize)
taptype = new TAPType(TAPDatatype.VARCHAR, (vottype.arraysize > 0) ? vottype.arraysize : NO_LENGTH);
else{
if (vottype.arraysize <= 0 || vottype.arraysize == VotType.NO_SIZE)
taptype = new TAPType(TAPDatatype.VARCHAR);
else if (vottype.arraysize == 1)
taptype = new TAPType(TAPDatatype.CHAR, 1);
else
taptype = new TAPType(TAPDatatype.CHAR, vottype.arraysize);
}
}
return taptype;
}
}
}
package tap.metadata;
/*
* This file is part of TAPLibrary.
*
* TAPLibrary 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.
*
* TAPLibrary 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 TAPLibrary. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2012 - UDS/Centre de Données astronomiques de Strasbourg (CDS)
*/
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
/**
* <p>
* Gathers all types used by a TAP service and described in the IVOA document for TAP.
* This class lets "translating" a DB type into a VOTable field type and vice-versa.
* You can also add some DB type aliases, that's to say other other names for the existing DB types:
* smallint, integer, bigint, real, double, binary, varbinary, char, varchar, blob, clob, timestamp, point, region.
* For instance: TEXT &lt;-&gt; VARCHAR.
* </p>
*
* @author Gr&eacute;gory Mantelet (CDS)
* @version 11/2011
*
* @see VotType
*/
public final class TAPTypes {
private static final Map<String,VotType> dbTypes;
private static final Map<String,String> dbTypeAliases;
private static final Map<VotType,String> votTypes;
public static final String SMALLINT = "SMALLINT";
public static final String INTEGER = "INTEGER";
public static final String BIGINT = "BIGINT";
public static final String REAL = "REAL";
public static final String DOUBLE = "DOUBLE";
public static final String BINARY = "BINARY";
public static final String VARBINARY = "VARBINARY";
public static final String CHAR = "CHAR";
public static final String VARCHAR = "VARCHAR";
public static final String BLOB = "BLOB";
public static final String CLOB = "CLOB";
public static final String TIMESTAMP = "TIMESTAMP";
public static final String POINT = "POINT";
public static final String REGION = "REGION";
/** No array size. */
public static final int NO_SIZE = -1;
/** Means '*' (i.e. char(*)). */
public static final int STAR_SIZE = -12345;
static{
dbTypes = new HashMap<String,VotType>(14);
votTypes = new HashMap<VotType,String>(7);
VotType type = new VotType("short", 1, null);
dbTypes.put(SMALLINT, type);
votTypes.put(type, SMALLINT);
type = new VotType("int", 1, null);
dbTypes.put(INTEGER, type);
votTypes.put(type, INTEGER);
type = new VotType("long", 1, null);
dbTypes.put(BIGINT, type);
votTypes.put(type, BIGINT);
type = new VotType("float", 1, null);
dbTypes.put(REAL, type);
votTypes.put(type, REAL);
type = new VotType("double", 1, null);
dbTypes.put(DOUBLE, type);
votTypes.put(type, DOUBLE);
dbTypes.put(BINARY, new VotType("unsignedByte", 1, null));
type = new VotType("unsignedByte", STAR_SIZE, null);
dbTypes.put(VARBINARY, type);
votTypes.put(type, VARBINARY);
dbTypes.put(CHAR, new VotType("char", 1, null));
type = new VotType("char", STAR_SIZE, null);
dbTypes.put(VARCHAR, type);
votTypes.put(type, VARCHAR);
type = new VotType("unsignedByte", STAR_SIZE, "adql:BLOB");
dbTypes.put(BLOB, type);
votTypes.put(type, BLOB);
type = new VotType("char", STAR_SIZE, "adql:CLOB");
dbTypes.put(CLOB, type);
votTypes.put(type, CLOB);
type = new VotType("char", STAR_SIZE, "adql:TIMESTAMP");
dbTypes.put(TIMESTAMP, type);
votTypes.put(type, TIMESTAMP);
type = new VotType("char", STAR_SIZE, "adql:POINT");
dbTypes.put(POINT, type);
votTypes.put(type, POINT);
type = new VotType("char", STAR_SIZE, "adql:REGION");
dbTypes.put(REGION, type);
votTypes.put(type, REGION);
dbTypeAliases = new HashMap<String,String>(8);
// PostgreSQL data types:
dbTypeAliases.put("INT2", SMALLINT);
dbTypeAliases.put("INT", INTEGER);
dbTypeAliases.put("INT4", INTEGER);
dbTypeAliases.put("INT8", BIGINT);
dbTypeAliases.put("FLOAT4", REAL);
dbTypeAliases.put("FLOAT8", DOUBLE);
dbTypeAliases.put("TEXT", VARCHAR);
dbTypeAliases.put("SPOINT", POINT);
}
/**
* Gets all DB types.
* @return An iterator on DB type name.
*/
public static final Iterator<String> getDBTypes(){
return dbTypes.keySet().iterator();
}
/**
* Gets all DB type aliases.
* @return An iterator on Entry&lt;String,String&gt; whose the key is the alias and the value is its corresponding DB type.
*/
public static final Iterator<Entry<String,String>> getDBTypeAliases(){
return dbTypeAliases.entrySet().iterator();
}
/**
* Gets all VOTable types.
* @return An iterator on {@link VotType}.
*/
public static final Iterator<VotType> getVotTypes(){
return votTypes.keySet().iterator();
}
/**
* <p>Gets the VOTable type corresponding to the given DB type (or a DB type alias).</p>
* <b>Important:</b>
* <ul>
* <li>Spaces before and after the DB type are automatically removed,</li>
* <li>The DB type is automatically formatted in UPPER-CASE,</li>
* <li>Nothing is done if the given DB type is <code>null</code> or empty.</li>
* </ul>
*
* @param dbType A DB type (ex: SMALLINT, INTEGER, VARCHAR, POINT, ...)
*
* @return The corresponding VOTable type or <code>null</code> if not found.
*/
public static final VotType getVotType(String dbType){
if (dbType == null)
return null;
// Normalize the type name (upper case and with no leading and trailing spaces):
dbType = dbType.trim().toUpperCase();
if (dbType.length() == 0)
return null;
// Search the corresponding VOTable type:
VotType votType = dbTypes.get(dbType);
// If no match, try again considering the given type as an alias:
if (votType == null)
votType = dbTypes.get(dbTypeAliases.get(dbType));
return votType;
}
/**
* <p>Gets the VOTable type (with the given arraysize) corresponding to the given DB type (or a DB type alias).</p>
* <b>Important:</b>
* <ul>
* <li>Spaces before and after the DB type are automatically removed,</li>
* <li>The DB type is automatically formatted in UPPER-CASE,</li>
* <li>Nothing is done if the given DB type is <code>null</code> or empty,</li>
* <li>The given arraysize is used only if the found VOTable type is not special (that's to say: <code>xtype</code> is <code>null</code>).</li>
* </ul>
*
* @param dbType A DB type (ex: SMALLINT, INTEGER, VARCHAR, POINT, ...)
* @param arraysize Arraysize to set in the found VOTable type.
*
* @return The corresponding VOTable type or <code>null</code> if not found.
*/
public static final VotType getVotType(String dbType, int arraysize){
VotType votType = getVotType(dbType);
// If there is a match, set the arraysize:
if (votType != null && votType.xtype == null && arraysize > 0)
votType = new VotType(votType.datatype, arraysize, null);
return votType;
}
/**
*
* <p>Gets the DB type corresponding to the given DB type alias.</p>
* <b>Important:</b>
* <ul>
* <li>Spaces before and after the DB type are automatically removed,</li>
* <li>The DB type is automatically formatted in UPPER-CASE,</li>
* <li>If the given DB type is not alias but directly a DB type, it is immediately return.</li>
* </ul>
*
* @param dbTypeAlias A DB type alias.
*
* @return The corresponding DB type or <code>null</code> if not found.
*/
public static final String getDBType(String dbTypeAlias){
if (dbTypeAlias == null)
return null;
// Normalize the type name:
dbTypeAlias = dbTypeAlias.trim().toUpperCase();
if (dbTypeAlias.length() == 0)
return null;
// Get the corresponding DB type:
if (dbTypes.containsKey(dbTypeAlias))
return dbTypeAlias;
else
return dbTypeAliases.get(dbTypeAlias);
}
/**
*
* <p>Gets the DB type corresponding to the given VOTable field type.</p>
* <b>Important:</b>
* <ul>
* <li>The research is made only on the following fields: <code>datatype</code> and <code>xtype</code>,</li>
* <li>Case <b>insensitive</b> research.</li>
* </ul>
*
* @param type A VOTable type.
*
* @return The corresponding DB type or <code>null</code> if not found.
*/
public static final String getDBType(final VotType type){
if (type == null)
return null;
return votTypes.get(type);
}
/**
* <p>Adds, replaces or removes a DB type alias.</p>
* <b>Important:</b>
* <ul>
* <li>Spaces before and after the DB type are automatically removed,</li>
* <li>The DB type is automatically formatted in UPPER-CASE,</li>
* <li>The same "normalizations" are done on the given alias (so the case sensitivity is ignored),</li>
* <li>Nothing is done if the given alias is <code>null</code> or empty,</li>
* <li>If the given DB type is <code>null</code>, the given alias is removed,</li>
* <li>Nothing is done if the given DB type (!= null) does not match with a known DB type.</li>
* </ul>
*
* @param alias A DB type alias (ex: spoint)
* @param dbType A DB type (ex: POINT).
*
* @return <code>true</code> if the association has been updated, <code>false</code> otherwise.
*/
public static final boolean putDBTypeAlias(String alias, String dbType){
if (alias == null)
return false;
// Normalize the given alias:
alias = alias.trim().toUpperCase();
if (alias.length() == 0)
return false;
// Check the existence of the given DB type:
if (dbType != null){
dbType = dbType.trim().toUpperCase();
if (dbType.length() == 0)
return false;
else if (!dbTypes.containsKey(dbType))
return false;
}
// Update the map of aliases:
if (dbType == null)
dbTypeAliases.remove(alias);
else
dbTypeAliases.put(alias, dbType);
return true;
}
/** SELF TEST */
public final static void main(final String[] args) throws Exception{
System.out.println("***** DB TYPES *****");
Iterator<String> itDB = TAPTypes.getDBTypes();
while(itDB.hasNext())
System.out.println("\t- " + itDB.next());
System.out.println("\n***** DB TYPE ALIASES *****");
Iterator<Entry<String,String>> itAliases = TAPTypes.getDBTypeAliases();
while(itAliases.hasNext()){
Entry<String,String> e = itAliases.next();
System.out.println("\t- " + e.getKey() + " = " + e.getValue());
}
System.out.println("\n***** VOTABLE TYPES *****");
Iterator<VotType> itVot = TAPTypes.getVotTypes();
while(itVot.hasNext())
System.out.println("\t- " + itVot.next());
byte[] buffer = new byte[1024];
int nbRead = 0;
String type = null;
System.out.print("\nDB Type ? ");
nbRead = System.in.read(buffer);
type = new String(buffer, 0, nbRead);
System.out.println(TAPTypes.getVotType(type));
int arraysize = 1;
String xtype = null;
VotType votType = null;
System.out.print("\nVOTable datatype ? ");
nbRead = System.in.read(buffer);
type = (new String(buffer, 0, nbRead)).trim();
System.out.print("VOTable arraysize ? ");
nbRead = System.in.read(buffer);
try{
arraysize = Integer.parseInt((new String(buffer, 0, nbRead)).trim());
}catch(NumberFormatException nfe){
arraysize = STAR_SIZE;
}
System.out.print("VOTable xtype ? ");
nbRead = System.in.read(buffer);
xtype = (new String(buffer, 0, nbRead)).trim();
if (xtype != null && xtype.length() == 0)
xtype = null;
votType = new VotType(type, arraysize, xtype);
System.out.println(TAPTypes.getDBType(votType));
}
}
...@@ -16,7 +16,8 @@ package tap.metadata; ...@@ -16,7 +16,8 @@ package tap.metadata;
* You should have received a copy of the GNU Lesser General Public License * You should have received a copy of the GNU Lesser General Public License
* along with TAPLibrary. If not, see <http://www.gnu.org/licenses/>. * along with TAPLibrary. If not, see <http://www.gnu.org/licenses/>.
* *
* Copyright 2012 - UDS/Centre de Données astronomiques de Strasbourg (CDS) * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
* Astronomishes Rechen Institute (ARI)
*/ */
import cds.savot.writer.SavotWriter; import cds.savot.writer.SavotWriter;
...@@ -29,25 +30,88 @@ import cds.savot.writer.SavotWriter; ...@@ -29,25 +30,88 @@ import cds.savot.writer.SavotWriter;
* <li><code>xtype</code>.</li> * <li><code>xtype</code>.</li>
* </ul> * </ul>
* *
* @author Gr&eacute;gory Mantelet (CDS) * @author Gr&eacute;gory Mantelet (CDS;ARI)
* @version 11/2011 * @version 06/2014
*/ */
public final class VotType { public final class VotType {
public final String datatype; /**
* All possible values for a VOTable datatype (i.e. boolean, short, char, ...).
*
* @author Gr&eacute;gory Mantelet (ARI) - gmantele@ari.uni-heidelberg.de
* @version 2.0 (06/2014)
* @since 2.0
*/
public static enum VotDatatype{
BOOLEAN("boolean"), SHORT("short"), INT("int"), LONG("long"), FLOAT("float"), DOUBLE("double"), CHAR("char"), UNSIGNED_BYTE("unsignedByte");
private final String strExpr;
private VotDatatype(final String str){
strExpr = (str == null || str.trim().length() == 0) ? name() : str;
}
@Override
public String toString(){
return strExpr;
}
}
/** Special VOTable type (XType) for TAP/DB type BLOB.
* @since 2.0*/
public final static String XTYPE_BLOB = "adql:BLOB";
/** Special VOTable type (XType) for TAP/DB type CLOB.
* @since 2.0 */
public final static String XTYPE_CLOB = "adql:CLOB";
/** Special VOTable type (XType) for TAP/DB type TIMESTAMP.
* @since 2.0 */
public final static String XTYPE_TIMESTAMP = "adql:TIMESTAMP";
/** Special VOTable type (XType) for TAP/DB type POINT.
* @since 2.0 */
public final static String XTYPE_POINT = "adql:POINT";
/** Special VOTable type (XType) for TAP/DB type REGION.
* @since 2.0 */
public final static String XTYPE_REGION = "adql:REGION";
/** No array size.
* @since 2.0 */
public static final int NO_SIZE = -1;
/** VOTable datatype
* @since 2.0 */
public final VotDatatype datatype;
/** A negative or null value means "*" (that's to say: an undetermined arraysize). */ /** A negative or null value means "*" (that's to say: an undetermined arraysize). */
public int arraysize; public final int arraysize;
/** If true, it means either "n*" (where n is the arraysize when > 0) or "*".
* @since 2.0*/
public final boolean unlimitedArraysize;
/** Special type specification (i.e. POINT, TIMESTAMP, ...). */
public final String xtype; public final String xtype;
/** /**
* @param datatype A datatype (ex: char, int, long, ...). <b>Null value forbidden</b> * Build a VOTable field type.
* @param arraysize A non-null positive integer. (any value &le; 0 will be considered as an undetermined arraysize). *
* @param datatype A datatype. <b>Null value forbidden</b>
* @param arraysize A non-null positive integer. (any value &le; 0 will be considered as an undetermined arraysize, that's to say {@link #NO_SIZE}).
* @param unlimitedSize Indicate whether a * must be appended at the end of the arraysize attribute (so in these 2 cases: "n*" or "*").
*/
public VotType(final VotDatatype datatype, final int arraysize, final boolean unlimitedSize){
this(datatype, arraysize, unlimitedSize, null);
}
/**
* Build a VOTable field type.
*
* @param datatype A datatype. <b>Null value forbidden</b>
* @param arraysize A non-null positive integer. (any value &le; 0 will be considered as an undetermined arraysize, that's to say {@link #NO_SIZE}).
* @param unlimitedSize Indicate whether a * must be appended at the end of the arraysize attribute (so in these 2 cases: "n*" or "*").
* @param xtype A special type (ex: adql:POINT, adql:TIMESTAMP, ...). Null value allowed. * @param xtype A special type (ex: adql:POINT, adql:TIMESTAMP, ...). Null value allowed.
*/ */
public VotType(final String datatype, final int arraysize, final String xtype){ public VotType(final VotDatatype datatype, final int arraysize, final boolean unlimitedSize, final String xtype){
if (datatype == null) if (datatype == null)
throw new NullPointerException("Null VOTable datatype !"); throw new NullPointerException("Missing VOTable datatype !");
this.datatype = datatype; this.datatype = datatype;
this.arraysize = arraysize; this.arraysize = (arraysize > 0) ? arraysize : NO_SIZE;
this.unlimitedArraysize = unlimitedSize;
this.xtype = xtype; this.xtype = xtype;
} }
...@@ -56,13 +120,7 @@ public final class VotType { ...@@ -56,13 +120,7 @@ public final class VotType {
if (obj == null) if (obj == null)
return false; return false;
try{ try{
VotType vot = (VotType)obj; return toString().equals(obj);
if (datatype.equalsIgnoreCase(vot.datatype)){
if (xtype == null)
return (vot.xtype == null);
else
return xtype.equalsIgnoreCase(vot.xtype);
}
}catch(ClassCastException cce){ }catch(ClassCastException cce){
; ;
} }
...@@ -71,7 +129,7 @@ public final class VotType { ...@@ -71,7 +129,7 @@ public final class VotType {
@Override @Override
public int hashCode(){ public int hashCode(){
return datatype.toLowerCase().hashCode(); return datatype.toString().hashCode();
} }
@Override @Override
...@@ -79,10 +137,13 @@ public final class VotType { ...@@ -79,10 +137,13 @@ public final class VotType {
StringBuffer str = new StringBuffer("datatype=\""); StringBuffer str = new StringBuffer("datatype=\"");
str.append(datatype).append('"'); str.append(datatype).append('"');
if (arraysize == TAPTypes.STAR_SIZE) if (arraysize > 0){
str.append(" arraysize=\"").append(SavotWriter.encodeAttribute("" + arraysize));
if (unlimitedArraysize)
str.append("*");
str.append('"');
}else if (unlimitedArraysize)
str.append(" arraysize=\"*\""); str.append(" arraysize=\"*\"");
else if (arraysize != TAPTypes.NO_SIZE && arraysize > 0)
str.append(" arraysize=\"").append(SavotWriter.encodeAttribute("" + arraysize)).append('"');
if (xtype != null) if (xtype != null)
str.append(" xtype=\"").append(SavotWriter.encodeAttribute(xtype)).append('"'); str.append(" xtype=\"").append(SavotWriter.encodeAttribute(xtype)).append('"');
...@@ -90,4 +151,13 @@ public final class VotType { ...@@ -90,4 +151,13 @@ public final class VotType {
return str.toString(); return str.toString();
} }
/**
* Convert this VOTable type definition into a TAPColumn type.
*
* @return The corresponding {@link TAPType}.
*/
public TAPType toTAPType(){
return TAPType.convertFromVotType(this);
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment