buildframework/helium/sf/java/metadata/src/com/nokia/helium/metadata/ORMFMPPLoader.java
/*
* Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of the License "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:
*
*/
package com.nokia.helium.metadata;
import java.io.File;
import java.util.List;
import java.util.Map;
import java.util.ArrayList;
import fmpp.Engine;
import fmpp.ProgressListener;
import fmpp.tdd.DataLoader;
import freemarker.template.TemplateCollectionModel;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateHashModel;
import freemarker.template.TemplateSequenceModel;
import freemarker.template.SimpleScalar;
import freemarker.template.SimpleNumber;
import freemarker.template.TemplateModelIterator;
import com.nokia.helium.jpa.ORMReader;
import org.apache.log4j.Logger;
import freemarker.ext.beans.BeanModel;
import freemarker.ext.beans.BeansWrapper;
/**
* Utility class to access the data from the database and used by FMPP
* templates.
*/
public class ORMFMPPLoader implements DataLoader {
//private ResultSet rs;
private static final int READ_LIMIT = 20000;
private static Logger log = Logger.getLogger(ORMFMPPLoader.class);
private ORMReader reader;
/**
* @see fmpp.tdd.DataLoader#load(fmpp.Engine, java.util.List)
*/
public Object load(Engine engine, List args) throws Exception {
//log.debug("args.size:" + args.size());
java.util.ListIterator iter = args.listIterator();
int argsSize = args.size();
if (argsSize < 1) {
throw new Exception("Input DB path should be provided to load into FMPP.");
}
ORMQueryModeModel model = new ORMQueryModeModel((String) (args.get(0)));
engine.setAttribute(this.getClass().toString(), model);
return model;
}
/**
* QueryModel (which supports hash, sequence, containers)
* arg[0] - dbpath
*
*/
private class ORMQueryModeModel implements TemplateHashModel, ProgressListener {
private String dbPath;
public ORMQueryModeModel(String path) {
File actualPath = new File(path);
String fileName = actualPath.getName();
dbPath = new File(actualPath.getParent(), fileName.toLowerCase()).getPath();
}
/*
* Gets the template model for the corresponding query
* @param query for which the model is returned.
* @return returns the template model for the query
*/
public QueryTemplateModel get(String mode) {
String retType = null;
String actualMode = mode;
//log.debug("mode: " + mode);
if (mode.startsWith("native")) {
String [] splitString = mode.split(":");
if (splitString.length == 2 ) {
actualMode = splitString[0];
retType = splitString[1];
//log.debug("actualMode " + actualMode);
//log.debug("retType " + retType);
}
}
return new QueryTemplateModel(dbPath, actualMode, retType);
}
public boolean isEmpty() {
return false;
}
/**
* {@inheritDoc}
*/
@Override
public void notifyProgressEvent(Engine engine, int event, File src,
int pMode, Throwable error, Object param) throws Exception {
//if (event == ProgressListener.EVENT_END_PROCESSING_SESSION) {
// log.debug("notifyProgressEvent - finalizeORM");
// ORMUtil.finalizeORM(dbPath);
//}
}
}
/*
* Internal class to handle the sql query and returns the data in either
* hash or sequence or containers.
*/
private class QueryTemplateModel implements TemplateHashModel {
private String dbPath;
private String queryMode;
private String returnType;
private TemplateModel resultObject;
public QueryTemplateModel(String path, String mode, String retType) {
dbPath = path;
queryMode = mode;
returnType = retType;
}
public TemplateModel get(String query) {
//log.debug("QueryTemplateModel: query" + query);
if (queryMode.equals("jpasingle")) {
//log.debug("query executing with single result mode");
resultObject = getModel(dbPath, query, returnType);
} else {
//log.debug("query executing with multiple result mode");
resultObject = new ORMQueryModel(dbPath, query, queryMode, returnType);
}
return resultObject;
}
private TemplateModel getModel(String dbPath, String query,
String returnType) {
ORMReader reader = new ORMReader(dbPath);
ORMSequenceModel model = new ORMSequenceModel(reader.executeSingleResult(query, returnType));
reader.close();
return model;
}
public boolean isEmpty() {
//log.debug("query hash isempty:");
return false;
}
}
private class ORMSequenceModel implements TemplateSequenceModel {
private List ormList = new ArrayList();
@SuppressWarnings("unchecked")
public ORMSequenceModel(Object obj) {
ormList.add(obj);
}
public int size() {
return ormList.size();
}
public TemplateModel get(int index) {
//log.debug("ORMSequenceModel.get: index: " + index);
if (index < ormList.size()) {
Object obj = ormList.get(index);
if (obj instanceof String) {
return new SimpleScalar((String)obj);
} else if (obj instanceof Number) {
return new SimpleNumber((Number)obj);
} else if (obj == null) {
return null;
} else {
return new ORMObjectModel(obj);
}
}
return null;
}
}
private class ORMQueryModel implements TemplateCollectionModel
{
private ORMReader ormReader;
private String queryType;
private String query;
private String returnType;
public ORMQueryModel(String dbPath, String queryString, String type, String retType) {
ormReader = new ORMReader(dbPath);
queryType = type;
query = queryString;
returnType = retType;
//log.debug("ORMQueryModel: query" + query);
}
/*
* Provides data via collection interface.
* @return the iterator model from which the data is accessed.
*/
public TemplateModelIterator iterator() {
//log.debug("iterator constructor called");
return new ORMTemplateModelIterator(ormReader, query, queryType, returnType);
}
}
/*
* Internal Iterator class which provides data as collection.
*/
private class ORMTemplateModelIterator implements TemplateModelIterator {
private String query;
private List<Map<String, Object>> rowList;
private int currentOffsetIndex;
private boolean finished;
private String returnType;
private boolean nativeQuery;
private ORMReader ormReader;
public ORMTemplateModelIterator(ORMReader reader, String queryString, String type, String retType) {
ormReader = reader;
query = queryString;
returnType = retType;
if (type.startsWith("native")) {
nativeQuery = true;
}
//log.debug("ORMTemplateModelIterator: query" + query);
}
/**
* {@inheritDoc}
*/
@SuppressWarnings("unchecked")
public TemplateModel next() {
//log.debug("ORMTemplateModelIterator: next");
Object toRet = null;
if (rowList != null) {
toRet = rowList.remove(0);
}
if (nativeQuery && returnType.equals("java.lang.String")) {
return new SimpleScalar((java.lang.String)toRet);
}
return new ORMObjectModel(toRet);
}
/**
* {@inheritDoc}
*/
@SuppressWarnings("unchecked")
public boolean hasNext() {
if (rowList == null || rowList.size() == 0) {
if (!finished) {
if (nativeQuery) {
if (returnType.equals("java.lang.String")) {
rowList = ormReader.executeNativeQuery(query, null);
} else {
rowList = ormReader.executeNativeQuery(query, returnType);
}
} else {
rowList = ormReader.executeQuery(query);
}
if (rowList == null || rowList.size() == 0) {
finished = true;
ormReader.close();
}
}
}
return !finished;
}
}
private class ORMObjectModel extends BeanModel {
public ORMObjectModel(Object obj) {
super(obj, new BeansWrapper());
}
}
}