/**********************************************************************************
* $URL:https://source.sakaiproject.org/svn/osp/trunk/warehouse/api-impl/src/java/org/theospi/portfolio/warehouse/impl/BaseChildWarehouseTask.java $
* $Id:BaseChildWarehouseTask.java 9134 2006-05-08 20:28:42Z chmaurer@iupui.edu $
***********************************************************************************
*
* Copyright (c) 2005, 2006, 2007, 2008 The Sakai Foundation
*
* Licensed under the Educational Community License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.opensource.org/licenses/ECL-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
**********************************************************************************/
package org.sakaiproject.warehouse.impl;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import org.quartz.JobExecutionException;
import org.sakaiproject.warehouse.service.ItemIndexInParentPropertyAccess;
import org.sakaiproject.warehouse.service.ParentPropertyAccess;
import org.sakaiproject.warehouse.service.*;
import org.sakaiproject.warehouse.service.PropertyAccess;
/**
* Created by IntelliJ IDEA.
* User: John Ellis
* Date: Nov 30, 2005
* Time: 4:58:05 PM
* To change this template use File | Settings | File Templates.
*/
public class BaseChildWarehouseTask implements ChildWarehouseTask {
private List fields;
private String insertStmt;
private String clearStmt;
private List complexFields;
private int batchSize = 1000;
private boolean isPrepared = false;
/**
* This is run after prepare
*/
public void execute(Object parent, Collection items, Connection connection)
throws JobExecutionException {
PreparedStatement ps = null;
isPrepared = false;
try {
int current = 0;
ps = connection.prepareStatement(getInsertStmt());
for (Iterator i=items.iterator();i.hasNext();) {
processItem(parent, i.next(), ps, current);
ps.addBatch();
current++;
if (current > batchSize) {
current = 0;
ps.executeBatch();
}
ps.clearParameters();
}
if (current > 0) {
ps.executeBatch();
}
}
catch (SQLException e) {
throw new JobExecutionException(new Exception("query: " + getInsertStmt(), e));
} catch (NullPointerException e) {
throw new JobExecutionException(new Exception(
"The BaseChildWarehouseTask.execute method parameter items is null. query identifier: " +
getInsertStmt(), e));
}
finally {
try {
ps.close();
}
catch (Exception e) {
// nothing to do here.
}
}
}
/**
* This method is run before execute. It ensures that the prepare functionality is only executed once
* @param Connection clears the database.
*/
public void prepare(Connection connection) {
try {
if(isPrepared) return;
connection.createStatement().execute(getClearStmt());
isPrepared = true;
if (getComplexFields() != null) {
for (Iterator i=getComplexFields().iterator();i.hasNext();) {
ChildFieldWrapper wrapper = (ChildFieldWrapper)i.next();
wrapper.getTask().prepare(connection);
}
}
}
catch (SQLException e) {
throw new RuntimeException(e);
}
}
protected void processItem(Object parent, Object item, PreparedStatement ps, int itemIndex)
throws JobExecutionException {
try {
int index = 1;
for (Iterator i=getFields().iterator();i.hasNext();) {
Object o = i.next();
if (o instanceof PropertyAccess) {
PropertyAccess pa = (PropertyAccess)o;
ps.setObject(index, pa.getPropertyValue(item));
}
else if (o instanceof ParentPropertyAccess) {
ParentPropertyAccess pa = (ParentPropertyAccess)o;
ps.setObject(index, pa.getPropertyValue(parent, item));
} else if (o instanceof ItemIndexInParentPropertyAccess){
ps.setInt(index, itemIndex);
}
index++;
}
// now, lets look for complex fields
if (getComplexFields() != null) {
for (Iterator i=getComplexFields().iterator();i.hasNext();) {
ChildFieldWrapper wrapper = (ChildFieldWrapper)i.next();
Object property = wrapper.getPropertyAccess().getPropertyValue(item);
Collection items = null;
//If the complex field isn't a Collection then
// build a collection out of the single class
// instance in the complex field
if(property instanceof Collection) {
items = (Collection)property;
} else {
items = new ArrayList();
if(property != null)
items.add(property);
}
// item becomes the new parent, items is the complex field (Collection)
wrapper.getTask().execute(item, items, ps.getConnection());
}
}
}
catch (Exception e) {
throw new JobExecutionException("error trying to prepare '" + insertStmt + "'", e, false);
}
}
public List getFields() {
return fields;
}
public void setFields(List fields) {
this.fields = fields;
}
public String getInsertStmt() {
return insertStmt;
}
public void setInsertStmt(String insertStmt) {
this.insertStmt = insertStmt;
}
public List getComplexFields() {
return complexFields;
}
public void setComplexFields(List complexFields) {
this.complexFields = complexFields;
}
public int getBatchSize() {
return batchSize;
}
public void setBatchSize(int batchSize) {
this.batchSize = batchSize;
}
public String getClearStmt() {
return clearStmt;
}
public void setClearStmt(String clearStmt) {
this.clearStmt = clearStmt;
}
}