Java tutorial
/* * #%L * Protempa Framework * %% * Copyright (C) 2012 - 2013 Emory University * %% * Licensed under the Apache 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.apache.org/licenses/LICENSE-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. * #L% */ package org.protempa.dest.table; import java.io.BufferedWriter; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; import org.arp.javautil.string.StringUtil; import org.protempa.KnowledgeSource; import org.protempa.KnowledgeSourceCache; import org.protempa.KnowledgeSourceCacheFactory; import org.protempa.KnowledgeSourceReadException; import org.protempa.PropositionDefinition; import org.protempa.ProtempaUtil; import org.protempa.dest.AbstractQueryResultsHandler; import org.protempa.dest.QueryResultsHandlerProcessingException; import org.protempa.dest.QueryResultsHandlerValidationFailedException; import org.protempa.proposition.Proposition; import org.protempa.proposition.UniqueId; /** * * @author Andrew Post */ public final class TableQueryResultsHandler extends AbstractQueryResultsHandler { private final char columnDelimiter; private final String[] rowPropositionIds; private final TableColumnSpec[] columnSpecs; private final boolean headerWritten; private final BufferedWriter out; private final Map<String, String> replace; private final KnowledgeSource knowledgeSource; private KnowledgeSourceCache ksCache; TableQueryResultsHandler(BufferedWriter out, char columnDelimiter, String[] rowPropositionIds, TableColumnSpec[] columnSpecs, boolean headerWritten, KnowledgeSource knowledgeSource) { checkConstructorArgs(rowPropositionIds, columnSpecs); this.columnDelimiter = columnDelimiter; this.rowPropositionIds = rowPropositionIds.clone(); ProtempaUtil.internAll(this.rowPropositionIds); this.columnSpecs = columnSpecs.clone(); this.headerWritten = headerWritten; this.out = out; this.replace = new HashMap<>(); this.replace.put(null, "(null)"); this.replace.put("", "(empty)"); this.knowledgeSource = knowledgeSource; } @Override public void validate() throws QueryResultsHandlerValidationFailedException { List<String> invalidPropIds = new ArrayList<>(); try { for (String propId : rowPropositionIds) { if (!knowledgeSource.hasPropositionDefinition(propId)) { invalidPropIds.add(propId); } } if (!invalidPropIds.isEmpty()) { throw new QueryResultsHandlerValidationFailedException( "Invalid row proposition id(s): " + StringUtils.join(invalidPropIds, ", ")); } int i = 1; for (TableColumnSpec columnSpec : columnSpecs) { try { columnSpec.validate(knowledgeSource); } catch (TableColumnSpecValidationFailedException ex) { throw new QueryResultsHandlerValidationFailedException( "Validation of column spec " + i + " failed", ex); } i++; } } catch (KnowledgeSourceReadException ex) { throw new QueryResultsHandlerValidationFailedException("Error during validation", ex); } } @Override public void start(Collection<PropositionDefinition> cache) throws QueryResultsHandlerProcessingException { Logger logger = Util.logger(); if (this.headerWritten) { try { List<String> columnNames = new ArrayList<>(); columnNames.add("KeyId"); for (TableColumnSpec columnSpec : this.columnSpecs) { logger.log(Level.FINE, "Processing columnSpec type {0}", columnSpec.getClass().getName()); String[] colNames = columnSpec.columnNames(this.knowledgeSource); assert colNames.length > 0 : "colNames must have length > 0"; for (int index = 0; index < colNames.length; index++) { String colName = colNames[index]; if (this.replace.containsKey(colName)) { colNames[index] = this.replace.get(colName); } } if (logger.isLoggable(Level.FINE)) { logger.log(Level.FINE, "Got the following columns for proposition {0}: {1}", new Object[] { StringUtils.join(this.rowPropositionIds, ", "), StringUtils.join(colNames, ", ") }); } for (String colName : colNames) { columnNames.add(colName); } } StringUtil.escapeAndWriteDelimitedColumns(columnNames, this.columnDelimiter, this.out); this.out.newLine(); } catch (KnowledgeSourceReadException ex1) { throw new QueryResultsHandlerProcessingException("Error reading knowledge source", ex1); } catch (IOException ex) { throw new QueryResultsHandlerProcessingException("Could not write header", ex); } } try { this.ksCache = new KnowledgeSourceCacheFactory().getInstance(this.knowledgeSource, cache, true); } catch (KnowledgeSourceReadException ex) { throw new QueryResultsHandlerProcessingException(ex); } } @Override public void handleQueryResult(String keyId, List<Proposition> propositions, Map<Proposition, List<Proposition>> forwardDerivations, Map<Proposition, List<Proposition>> backwardDerivations, Map<UniqueId, Proposition> references) throws QueryResultsHandlerProcessingException { int n = this.columnSpecs.length; Util.logger().log(Level.FINER, "Processing keyId {0}", keyId); for (Proposition prop : propositions) { if (!org.arp.javautil.arrays.Arrays.contains(this.rowPropositionIds, prop.getId())) { continue; } try { StringUtil.escapeAndWriteDelimitedColumn(keyId, this.columnDelimiter, this.out); if (n > 0) { this.out.write(this.columnDelimiter); } for (int i = 0; i < n; i++) { TableColumnSpec columnSpec = this.columnSpecs[i]; columnSpec.columnValues(keyId, prop, forwardDerivations, backwardDerivations, references, this.ksCache, this.replace, this.columnDelimiter, this.out); if (i < n - 1) { this.out.write(this.columnDelimiter); } else { this.out.newLine(); } } } catch (IOException ex) { throw new QueryResultsHandlerProcessingException("Could not write row" + ex); } } } private void checkConstructorArgs(String[] rowPropositionIds, TableColumnSpec[] columnSpecs) { ProtempaUtil.checkArray(rowPropositionIds, "rowPropositionIds"); ProtempaUtil.checkArray(columnSpecs, "columnSpecs"); } }