Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[birt-dev] How to get metadata from JPA for create the ResultSetMetaData

Hi BIRT community,

Actually I'm  to make a JPA ODA driver extensions for BIRT, for that I
am based on the implementation in Hibernate ODA Extension since it is
an implementation of JPA.

The problem I have is to implement the method prepare( ) of the
interface for "IQuery"
for sets up array lists to contain the columns, column types, and column
classes.

Here I show the code of this method based on the Implementation from
Hibernate and commenting on the part to embed code for support with
JPA wanting :

public void prepare( String query ) throws OdaException
	{
		Query qry = null;
		//Test the connection
                //testConnection( );
		//holds the column types

		ArrayList arColsType = new ArrayList();
		ArrayList arCols = new ArrayList();
               ArrayList arColClass = new ArrayList();
	
	
		//holds the column names, also used for labels
		String[] props = null;
		try{
			EntityManager em = JPAUtil.currentSession();
			//Create a Hibernate Query	
			query = query.replaceAll("[\\n\\r]+"," ");
			query =query.trim();
			qry = em.createQuery(query);// Create an instance of Query for
executing a  Java Persistence query language statement
			
	        /*In Hibernate is like this:
			Get the list of return types from the query
			Type[] qryReturnTypes = qry.getReturnTypes();*/
			
			//When specifing the HQL "from object" the returned type is a
Hibernate EntityType
			//When the columns are specified the returned values are normal data types
			//The first half of this if statment handles the EntityType, the
else handles the
			//other case.
			//We are not handling multipe result sets.
			if( qryReturnTypes.length > 0 && qryReturnTypes[0].isEntityType()){
				for(int j=0; j< qryReturnTypes.length; j++){
					//Get the classname and use utility function to retrieve data types
					String clsName=qryReturnTypes[j].getName();
					//props holds the column names
					props = HibernateUtil.getHibernateProp(clsName);
					for( int x = 0; x < props.length; x++){
						String propType = HibernateUtil.getHibernatePropTypes(clsName, props[x]);
						//Verify that the data type is valid
						if( DataTypes.isValidType(propType)){
							arColsType.add(propType);
							//Only do this on Entity Types so we dont have a name collision
							arCols.add(props[x]);
							arColClass.add(clsName);							
						}else{
							throw new OdaException(
Messages.getString("Statement.SOURCE_DATA_ERROR") );
						}
					}
				}
			}else{
				//Extract the column names from the query
				props = extractColumns(qry.getQueryString());
				//Get the return types from the Type[]
				for(int t=0; t < qryReturnTypes.length; t++){
					//Verify that the data type is valid
					if( DataTypes.isValidType(qryReturnTypes[t].getName())){
						arColsType.add(qryReturnTypes[t].getName());
						arCols.add(props[t]);
					}else{
						throw new OdaException(
Messages.getString("Statement.SOURCE_DATA_ERROR") );
					}					
				}
				
			}
		}catch(Exception e){
			throw new OdaException( e.getLocalizedMessage() );
		}
		//this example does not enforce unique column names
		//Create a new ResultSetMetaData object passing in the column names
and data types
		
		//Have to remove . which BIRT does not allow
		String[] arLabels = (String[])arCols.toArray(new String[arCols.size()]);
		for(int j=0; j < arLabels.length; j++){
			arLabels[j] = arLabels[j].replace('.', ':');
		}
		
		this.resultSetMetaData = new ResultSetMetaData( arLabels,
				(String[])arColsType.toArray(new String[arColsType.size()]),
				arLabels,
				(String[])arColClass.toArray(new String[arColClass.size()]));
		//query is saved for execution
		this.query = query;
		
		
	}// end of Prepare()



In the implemntation the Hibernate ODA, is used the API of HIbernate
to obtain the metadata of the query, but in JPA doesn't have something
similar.
The same happen to implement the method Object getResult (int rstcol)
on the interface IResulSet.
I thought use reflection to obtain such metada, I am not very familiar
with it but could be a probable solution.

I will be grateful for all the help that I can provide me.

Thanks.


Back to the top