| /** |
| * Copyright (c) 2010-2012 Kenn Hussey and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Common Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/cpl-v10.html |
| * |
| * Contributors: |
| * Kenn Hussey - Initial API and implementation |
| */ |
| package org.eclipse.emf.oda.ecore.impl; |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.InputStream; |
| import java.io.Reader; |
| import java.io.Serializable; |
| import java.io.StringReader; |
| import java.math.BigDecimal; |
| import java.math.BigInteger; |
| import java.sql.Date; |
| import java.sql.Time; |
| import java.sql.Timestamp; |
| |
| import org.eclipse.datatools.connectivity.oda.IBlob; |
| import org.eclipse.datatools.connectivity.oda.IClob; |
| import org.eclipse.datatools.connectivity.oda.IResultSet; |
| import org.eclipse.datatools.connectivity.oda.IResultSetMetaData; |
| import org.eclipse.datatools.connectivity.oda.OdaException; |
| import org.eclipse.emf.common.util.EList; |
| import org.eclipse.emf.ecore.EClassifier; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.EStructuralFeature; |
| import org.eclipse.emf.ecore.EcorePackage; |
| import org.eclipse.emf.oda.ecore.util.StringUtil; |
| |
| |
| /** |
| * Implementation of IResultSet for EMF ODA runtime driver. |
| */ |
| public abstract class ResultSet implements IResultSet |
| { |
| /** |
| * An implementation of IBlog for byte arrays. |
| */ |
| protected static class Blob implements IBlob |
| { |
| protected final byte[] data; |
| |
| protected Blob(byte[] data) |
| { |
| this.data = data; |
| } |
| |
| public InputStream getBinaryStream() throws OdaException |
| { |
| return new ByteArrayInputStream(data); |
| } |
| |
| public byte[] getBytes(long position, int length) throws OdaException |
| { |
| // let ODA consumer helper framework provide default implementation |
| throw new UnsupportedOperationException(); |
| } |
| |
| public long length() throws OdaException |
| { |
| return data.length; |
| } |
| } |
| |
| /** |
| * An implementation of IClob for strings. |
| */ |
| protected static class Clob implements IClob |
| { |
| protected final String data; |
| |
| protected Clob(String data) |
| { |
| this.data = data; |
| } |
| |
| public Reader getCharacterStream() throws OdaException |
| { |
| return new StringReader(data); |
| } |
| |
| public String getSubString(long position, int length) throws OdaException |
| { |
| // let ODA consumer helper framework provide default implementation |
| throw new UnsupportedOperationException(); |
| } |
| |
| public long length() throws OdaException |
| { |
| return data.length(); |
| } |
| } |
| |
| /** |
| * A wrapper for Java objects which works around the fact that EMF objects are not (Java) |
| * serializable and which provides a formatted text representation. |
| */ |
| public static class JavaObject implements Serializable |
| { |
| private static final long serialVersionUID = 1L; |
| |
| protected transient Object object = null; |
| |
| public JavaObject(Object object) |
| { |
| super(); |
| |
| this.object = object; |
| } |
| |
| public Object getObject() |
| { |
| return object; |
| } |
| |
| @Override |
| public String toString() |
| { |
| return StringUtil.getText(object); |
| } |
| } |
| |
| /** |
| * A set of results that contains instances of classes. |
| */ |
| protected static class EClass extends ResultSet |
| { |
| protected final ResultSetMetaData.EClass metaData; |
| |
| protected EClass(org.eclipse.emf.ecore.EClass type, EList< ? > results) |
| { |
| super(results); |
| |
| metaData = new ResultSetMetaData.EClass(type); |
| } |
| |
| public IResultSetMetaData getMetaData() throws OdaException |
| { |
| return metaData; |
| } |
| |
| public int findColumn(String columnName) throws OdaException |
| { |
| if (ResultSetMetaData.EClass.FIRST_COLUMN_NAME.equals(columnName)) |
| { |
| return 1; |
| } |
| else |
| { |
| EStructuralFeature feature = metaData.type.getEStructuralFeature(columnName); |
| |
| if (feature == null) |
| { |
| throw new OdaException(new IllegalArgumentException(String.valueOf(columnName))); |
| } |
| |
| return metaData.type.getFeatureID(feature) + 1; |
| } |
| } |
| |
| @Override |
| protected Object getValue(int index) throws OdaException |
| { |
| if (cursor < 1) |
| { |
| throw new OdaException(new IllegalStateException()); |
| } |
| |
| EObject self = (EObject)results.get(cursor - 1); |
| |
| if (index == 1) |
| { |
| wasNull = false; |
| return self; |
| } |
| else |
| { |
| Object value = self.eGet(metaData.type.getEStructuralFeature(index - 2)); |
| wasNull = value == null; |
| return value; |
| } |
| } |
| } |
| |
| /** |
| * A set of results that contains values of data types. |
| */ |
| protected static class EDataType extends ResultSet |
| { |
| protected final ResultSetMetaData.EDataType metaData; |
| |
| protected EDataType(org.eclipse.emf.ecore.EDataType type, EList< ? > results) |
| { |
| super(results); |
| |
| metaData = new ResultSetMetaData.EDataType(type); |
| } |
| |
| public IResultSetMetaData getMetaData() throws OdaException |
| { |
| return metaData; |
| } |
| |
| public int findColumn(String columnName) throws OdaException |
| { |
| if (ResultSetMetaData.EDataType.FIRST_COLUMN_NAME.equals(columnName)) |
| { |
| return 1; |
| } |
| else |
| { |
| throw new OdaException(new IllegalArgumentException(String.valueOf(columnName))); |
| } |
| } |
| |
| @Override |
| protected Object getValue(int index) throws OdaException |
| { |
| if (cursor < 1) |
| { |
| throw new OdaException(new IllegalStateException()); |
| } |
| |
| Object value = results.get(cursor - 1); |
| wasNull = value == null; |
| return value; |
| } |
| } |
| |
| protected final EList< ? > results; |
| protected int maxRows = 0; |
| |
| protected int cursor = 0; |
| protected boolean wasNull = false; |
| |
| /** |
| * Creates a result set of the appropriate kind, depending on whether the specified |
| * list of results contains instances of classes or values of data types. |
| * @param type the type of objects in the list of results |
| * @param results the list of results from executing a query |
| * @return a result set of the appropriate kind |
| */ |
| public static IResultSet create(EClassifier type, EList< ? > results) |
| { |
| if (type instanceof org.eclipse.emf.ecore.EClass) |
| { |
| return new EClass((org.eclipse.emf.ecore.EClass)type, results); |
| } |
| else |
| { |
| return new EDataType((org.eclipse.emf.ecore.EDataType)type, results); |
| } |
| } |
| |
| protected ResultSet(EList< ? > results) |
| { |
| super(); |
| |
| this.results = results; |
| } |
| |
| public void setMaxRows(int max) throws OdaException |
| { |
| if (max < 0) |
| { |
| throw new OdaException(new IllegalArgumentException(String.valueOf(max))); |
| } |
| |
| maxRows = max; |
| } |
| |
| public boolean next() throws OdaException |
| { |
| if (cursor < results.size() && (maxRows == 0 || cursor < maxRows)) |
| { |
| cursor++; |
| return true; |
| } |
| |
| return false; |
| } |
| |
| public void close() throws OdaException |
| { |
| cursor = 0; // reset row counter |
| } |
| |
| public int getRow() throws OdaException |
| { |
| return cursor; |
| } |
| |
| /** |
| * Returns the value (of the feature) at the specified index. |
| * @param index the 1-based index of the desired value |
| * @return the value |
| * @throws OdaException if data source error occurs |
| */ |
| protected abstract Object getValue(int index) throws OdaException; |
| |
| public String getString(int index) throws OdaException |
| { |
| switch (getMetaData().getColumnType(index)) |
| { |
| default: |
| Object value = getValue(index); |
| return wasNull ? null : String.valueOf(value); |
| } |
| } |
| |
| public String getString(String columnName) throws OdaException |
| { |
| return getString(findColumn(columnName)); |
| } |
| |
| public int getInt(int index) throws OdaException |
| { |
| switch (getMetaData().getColumnType(index)) |
| { |
| case EcorePackage.EBYTE: |
| case EcorePackage.EBYTE_OBJECT: |
| { |
| Object value = getValue(index); |
| return wasNull ? 0 : Integer.valueOf((Byte)value); |
| } |
| case EcorePackage.ECHAR: |
| case EcorePackage.ECHARACTER_OBJECT: |
| { |
| Object value = getValue(index); |
| return wasNull ? 0 : Integer.valueOf((Character)value); |
| } |
| case EcorePackage.EINT: |
| case EcorePackage.EINTEGER_OBJECT: |
| { |
| Object value = getValue(index); |
| return wasNull ? 0 : (Integer)value; |
| } |
| case EcorePackage.ESHORT: |
| case EcorePackage.ESHORT_OBJECT: |
| { |
| Object value = getValue(index); |
| return wasNull ? 0 : Integer.valueOf((Short)value); |
| } |
| case EcorePackage.ELONG: |
| case EcorePackage.ELONG_OBJECT: |
| { |
| Object value = getValue(index); |
| return wasNull ? 0 : Integer.valueOf(((Long)value).intValue()); |
| } |
| default: |
| throw new OdaException(new IllegalArgumentException(String.valueOf(index))); |
| } |
| } |
| |
| public int getInt(String columnName) throws OdaException |
| { |
| return getInt(findColumn(columnName)); |
| } |
| |
| public double getDouble(int index) throws OdaException |
| { |
| switch (getMetaData().getColumnType(index)) |
| { |
| case EcorePackage.EDOUBLE: |
| case EcorePackage.EDOUBLE_OBJECT: |
| { |
| Object value = getValue(index); |
| return wasNull ? 0 : (Double)value; |
| } |
| case EcorePackage.EFLOAT: |
| case EcorePackage.EFLOAT_OBJECT: |
| { |
| Object value = getValue(index); |
| return wasNull ? 0 : Double.valueOf((Float)value); |
| } |
| default: |
| throw new OdaException(new IllegalArgumentException(String.valueOf(index))); |
| } |
| } |
| |
| public double getDouble(String columnName) throws OdaException |
| { |
| return getDouble(findColumn(columnName)); |
| } |
| |
| public BigDecimal getBigDecimal(int index) throws OdaException |
| { |
| switch (getMetaData().getColumnType(index)) |
| { |
| case EcorePackage.EBIG_DECIMAL: |
| return (BigDecimal)getValue(index); |
| case EcorePackage.EBIG_INTEGER: |
| Object value = getValue(index); |
| return wasNull ? null : new BigDecimal((BigInteger)value); |
| default: |
| throw new OdaException(new IllegalArgumentException(String.valueOf(index))); |
| } |
| } |
| |
| public BigDecimal getBigDecimal(String columnName) throws OdaException |
| { |
| return getBigDecimal(findColumn(columnName)); |
| } |
| |
| public Date getDate(int index) throws OdaException |
| { |
| switch (getMetaData().getColumnType(index)) |
| { |
| case EcorePackage.EDATE: |
| Object value = getValue(index); |
| return wasNull ? null : new Date(((java.util.Date)value).getTime()); |
| default: |
| throw new OdaException(new IllegalArgumentException(String.valueOf(index))); |
| } |
| } |
| |
| public Date getDate(String columnName) throws OdaException |
| { |
| return getDate(findColumn(columnName)); |
| } |
| |
| public Time getTime(int index) throws OdaException |
| { |
| switch (getMetaData().getColumnType(index)) |
| { |
| case EcorePackage.EDATE: |
| Object value = getValue(index); |
| return wasNull ? null : new Time(((java.util.Date)value).getTime()); |
| default: |
| throw new OdaException(new IllegalArgumentException(String.valueOf(index))); |
| } |
| } |
| |
| public Time getTime(String columnName) throws OdaException |
| { |
| return getTime(findColumn(columnName)); |
| } |
| |
| public Timestamp getTimestamp(int index) throws OdaException |
| { |
| switch (getMetaData().getColumnType(index)) |
| { |
| case EcorePackage.EDATE: |
| Object value = getValue(index); |
| return wasNull ? null : new Timestamp(((java.util.Date)value).getTime()); |
| default: |
| throw new OdaException(new IllegalArgumentException(String.valueOf(index))); |
| } |
| } |
| |
| public Timestamp getTimestamp(String columnName) throws OdaException |
| { |
| return getTimestamp(findColumn(columnName)); |
| } |
| |
| public IBlob getBlob(int index) throws OdaException |
| { |
| switch (getMetaData().getColumnType(index)) |
| { |
| case EcorePackage.EBYTE_ARRAY: |
| Object value = getValue(index); |
| return wasNull ? null : new Blob((byte[])value); |
| default: |
| throw new OdaException(new IllegalArgumentException(String.valueOf(index))); |
| } |
| } |
| |
| public IBlob getBlob(String columnName) throws OdaException |
| { |
| return getBlob(findColumn(columnName)); |
| } |
| |
| public IClob getClob(int index) throws OdaException |
| { |
| switch (getMetaData().getColumnType(index)) |
| { |
| case EcorePackage.ESTRING: |
| Object value = getValue(index); |
| return wasNull ? null : new Clob((String)value); |
| default: |
| throw new OdaException(new IllegalArgumentException(String.valueOf(index))); |
| } |
| } |
| |
| public IClob getClob(String columnName) throws OdaException |
| { |
| return getClob(findColumn(columnName)); |
| } |
| |
| public boolean getBoolean(int index) throws OdaException |
| { |
| switch (getMetaData().getColumnType(index)) |
| { |
| case EcorePackage.EBOOLEAN: |
| case EcorePackage.EBOOLEAN_OBJECT: |
| Object value = getValue(index); |
| return wasNull ? Boolean.FALSE : (Boolean)value; |
| default: |
| throw new OdaException(new IllegalArgumentException(String.valueOf(index))); |
| } |
| } |
| |
| public boolean getBoolean(String columnName) throws OdaException |
| { |
| return getBoolean(findColumn(columnName)); |
| } |
| |
| public Object getObject(int index) throws OdaException |
| { |
| switch (getMetaData().getColumnType(index)) |
| { |
| case EcorePackage.EJAVA_OBJECT: |
| return new JavaObject(getValue(index)); |
| default: |
| return getValue(index); |
| } |
| } |
| |
| public Object getObject(String columnName) throws OdaException |
| { |
| return getObject(findColumn(columnName)); |
| } |
| |
| public boolean wasNull() throws OdaException |
| { |
| return wasNull; |
| } |
| } |