package de.uni_luebeck.inb.krabbenhoeft.eQTL.server; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import org.hibernate.Session; import org.hibernate.Transaction; import com.google.gwt.user.server.rpc.RemoteServiceServlet; import de.uni_luebeck.inb.krabbenhoeft.eQTL.api.gwt.DataProcessing; import de.uni_luebeck.inb.krabbenhoeft.eQTL.api.gwt.DataSetLayerOverview; import de.uni_luebeck.inb.krabbenhoeft.eQTL.api.gwt.DataSetProcessorOverview; import de.uni_luebeck.inb.krabbenhoeft.eQTL.entities.ColumnForDataSetLayer; import de.uni_luebeck.inb.krabbenhoeft.eQTL.entities.DataSet; import de.uni_luebeck.inb.krabbenhoeft.eQTL.entities.DataSetLayer; import de.uni_luebeck.inb.krabbenhoeft.eQTL.entities.HajoEntity; import de.uni_luebeck.inb.krabbenhoeft.eQTL.entities.ProcessingParameters; import de.uni_luebeck.inb.krabbenhoeft.eQTL.server.helpers.persistence.RunWithHibernate; public class DataProcessingService extends RemoteServiceServlet implements DataProcessing { private static final long serialVersionUID = 1L; public DataSetProcessorOverview[] enumerateProcessors(final Integer dataSetLayerKey) { return new RunWithHibernate<DataSetProcessorOverview[]>() { public DataSetProcessorOverview[] work(Transaction transaction, Session session) throws Exception { DataSetLayer dataSetLayer = (DataSetLayer) session.load(DataSetLayer.class, dataSetLayerKey); final Set<DataSetProcessorFactory> factories = ProcessorRegistry.getFactoriesFor(dataSetLayer.getColumns()); ArrayList<DataSetProcessorOverview> processorOverviews = new ArrayList<DataSetProcessorOverview>(); for (DataSetProcessorFactory factory : factories) { DataSetProcessorOverview overview = new DataSetProcessorOverview(); overview.key = factory.getClass().getName(); overview.name = factory.getName(); overview.parameterDescription = factory.getParameterDescription(dataSetLayer.getColumns()); processorOverviews.add(overview); } return processorOverviews.toArray(new DataSetProcessorOverview[0]); } }.run(); } public DataSetLayerOverview applyProcessor(final Integer dataSetKey, final Integer sourceDataSetLayerKey, final String processorKey, final String processorConfiguration) { final String[] command = new String[1]; final DataSetLayerOverview dataSetLayerOverview = new RunWithHibernate<DataSetLayerOverview>() { public DataSetLayerOverview work(Transaction transaction, Session session) throws Exception { DataSetProcessorFactory factory = getFacoryByKey(processorKey); final DataSetProcessor processor = factory.configure(processorConfiguration); final DataSetLayer sourceDataSetLayer = (DataSetLayer) session.load(DataSetLayer.class, sourceDataSetLayerKey); final List<ColumnForDataSetLayer> columns = new ArrayList<ColumnForDataSetLayer>(); for (ColumnForDataSetLayer column : sourceDataSetLayer.getColumns()) { columns.add(new ColumnForDataSetLayer(column)); } final List<ColumnForDataSetLayer> dataTypeAfterTransformation = processor.getDataTypeAfterTransformation(columns); final String params; if (processorConfiguration.length() > 0) params = " (" + processorConfiguration + ")"; else params = ""; final String operationFromLastLayer = sourceDataSetLayer.getKey() + ": " + factory.getName() + params; final DataSet sourceDataSet = (DataSet) session.load(DataSet.class, dataSetKey); final DataSetLayer targetDataSetLayer = DataSetHelpers.addLayerToDataSet(session, sourceDataSet, dataTypeAfterTransformation, operationFromLastLayer); final Integer targetDataSetLayerKey = targetDataSetLayer.getKey(); final int preferredItemsPerProcessor = processor.getPreferredItemsPerProcessor(); final int preferredNumberOfParallelRunningProcessors = processor.getPreferredNumberOfParallelRunningProcessors(); double blocksPerProcessor = (double) preferredItemsPerProcessor / (double) sourceDataSetLayer.getNumberOfItems() * (double) HajoEntity.NUMBER_OF_PARALLEL_BLOCK_IDS; blocksPerProcessor = Math.max(1.0f, blocksPerProcessor); double currentParallelBlock = 0.99; // to help in case we get rounding problems int lastBlockId = 0; while (lastBlockId <= HajoEntity.NUMBER_OF_PARALLEL_BLOCK_IDS) { ProcessingParameters parameters = new ProcessingParameters(); parameters.setProcessorConfiguration(processorConfiguration); parameters.setProcessorKey(processorKey); parameters.setSourceDataSetLayerKey(sourceDataSetLayerKey); parameters.setSourceParallelBlockIdMin(lastBlockId); parameters.setTargetDataSetLayerKey(targetDataSetLayerKey); currentParallelBlock += blocksPerProcessor; lastBlockId = (int) Math.ceil(currentParallelBlock); parameters.setSourceParallelBlockIdMax(lastBlockId); session.persist(parameters); } command[0] = "/data_set_processor?layer=" + targetDataSetLayerKey + "&workingSetSize=" + preferredNumberOfParallelRunningProcessors; return DataSetHelpers.generateOverviewForDataSetLayer(dataSetKey, targetDataSetLayer); } }.run(); invokeSelfAsync(getBasePath() + command[0]); return dataSetLayerOverview; } private String getBasePath() { System.out.println("getBasePath()"); String path = getThreadLocalRequest().getRequestURL().toString(); path = path.substring(0, path.indexOf('/', 9)); System.out.println("getBasePath() = " + path); return path; } private static final ExecutorService threadPool = Executors.newCachedThreadPool(); public static void invokeSelfAsync(final String command) { System.out.println("invokeSelfAsync: " + command); threadPool.execute(runnableForCommand(command)); } public static Runnable runnableForCommand(final String command) { return new Runnable() { public void run() { try { new URL(command).openStream().close(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }; } public static DataSetProcessorFactory getFacoryByKey(String processorKey) { DataSetProcessorFactory factory; try { factory = (DataSetProcessorFactory) Class.forName(processorKey).newInstance(); } catch (InstantiationException e) { throw new RuntimeException("Could not create processor factory", e); } catch (IllegalAccessException e) { throw new RuntimeException("Could not create processor factory", e); } catch (ClassNotFoundException e) { throw new RuntimeException("Could not create processor factory. Maybe the processorKey is invalid?", e); } return factory; } }