Java tutorial
/*- * Copyright 2009 Diamond Light Source Ltd., Science and Technology * Facilities Council Daresbury Laboratory * * This file is part of GDA. * * GDA is free software: you can redistribute it and/or modify it under the * terms of the GNU General Public License version 3 as published by the Free * Software Foundation. * * GDA is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along * with GDA. If not, see <http://www.gnu.org/licenses/>. */ package gda.hrpd.sample; import java.io.File; import java.io.IOException; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import gda.configuration.properties.LocalProperties; import gda.data.PathConstructor; import gda.factory.ConfigurableBase; import gda.factory.FactoryException; import gda.factory.Localizable; import gda.hrpd.SampleInfo; import gda.hrpd.data.ExcelWorkbook; import gda.jython.JythonServerFacade; import gda.observable.IObserver; import gda.observable.ObservableComponent; /** * This class reads the sample information data from a table in an Excel spreadsheet (default to sheet 0) and/or writes * experiment summary or metadata for each sample to a second spreadsheet. The default file name of this Excel file is * {@code Sample.xls}, which may be configured using java property {@code gda.data.sample.information.file} or in its * XML configuration element {@code <sampleInfoFile>}. The default directory where this spreadsheet is expected to be * should be user's home directory. */ @SuppressWarnings("serial") public class Sample extends ConfigurableBase implements Localizable, SampleInfo { private static final Logger logger = LoggerFactory.getLogger(Sample.class); private String carouselNo; // user input information on samples, mapped onto the template private String sampleID; private String sampleName; private String description; private String title; private String comment; // gda generated experiment metadata private String runNumber; private String date; private String time; private String beamline; private String project; private String experiment; private String wavelength; private String temperature; private String filename; private HSSFSheet sampleInfo; private HSSFSheet experimentSummary; private String sampleInfoFile; private int rowOffset = 0; private String name = "Sample"; private boolean saveExperimentSummary = false; private ExcelWorkbook excel; private ObservableComponent observableComponent = new ObservableComponent(); private boolean local = false; private boolean configureAtStartup = false; private boolean opened = false; /** */ public Sample() { } @Override public void configure() throws FactoryException { if (!isConfigured()) { if ((sampleInfoFile = getSampleInfoFile()) != null) { // XML object configuration if (sampleInfoFile.startsWith("/")) { this.filename = sampleInfoFile; } else { // assume the file is at user's home directory String processingDir = LocalProperties.getVarDir(); this.filename = processingDir + sampleInfoFile; } } else { // if XML does not configure, using property sampleInfoFile = LocalProperties.get("gda.data.sample.information.file", "SampleInfo.xls"); if (sampleInfoFile.startsWith("/")) { this.filename = sampleInfoFile; } else { // assume the file is at user's home directory String processingDir = LocalProperties.getVarDir(); this.filename = processingDir + sampleInfoFile; } } File file = new File(this.filename); if (!file.exists()) { logger.debug("Cannot find Sample Information file {}.", this.filename); logger.info("You may maunally input information per sample using object 'si' from JythonTerminal."); // sample information object will not be configured. return; } if (!file.canRead()) { logger.warn( "Can not read from file {}. Permission denied. Scan will not be able to read data from this file.", this.filename); } if (!file.canWrite()) { logger.warn( "Can not write to file {}. Permission denied. Scan will not be able to save data to this file. ", this.filename); } setConfigured(true); } } /** * open the workbook */ @Override public void open() { try { excel = new ExcelWorkbook(this.filename); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } if ((sampleInfo = excel.getSheet("Sample")) == null) { sampleInfo = excel.getSheetAt(0); } if ((experimentSummary = excel.getSheet("ExperimentSummary")) == null) { if (isSaveExperimentSummary()) { try { experimentSummary = excel.createSheet("ExperimentSummary"); } catch (IOException e) { logger.warn("{}, No Experiement Summary will be saved.", e.getMessage()); } } } opened = true; } /** * Closes the workbook. */ @Override public void close() { excel.close(); } /** * prints the current sample information to terminal. */ @Override public void values() { JythonServerFacade jsf = JythonServerFacade.getInstance(); jsf.print("CarouselNo=" + getCarouselNo()); jsf.print("SampleID=" + getSampleID()); jsf.print("SampleName=" + getSampleName()); jsf.print("Description=" + getDescription()); jsf.print("Title=" + getTitle()); jsf.print("Comment=" + getComment()); } /** * read existing data only {@inheritDoc} * * @see gda.hrpd.SampleInfo#loadSampleInfo(int) */ @Override public void loadSampleInfo(int sampleNo) { if (!opened) { logger.error("Sample Information File is not opened yet."); throw new IllegalStateException("Sample Information file " + this.filename + " must be opened first."); } logger.info("Load sample information from {} for sample number {}", getSampleInfoFile(), sampleNo); HSSFRow row = sampleInfo.getRow(sampleNo + rowOffset); if (row == null) { logger.error("specified sample Number {} does not exist.", sampleNo); JythonServerFacade.getInstance() .print("No sample information is provided for sample number " + sampleNo); } else { carouselNo = excel.getCellValue(row.getCell(0)); sampleID = excel.getCellValue(row.getCell(1)); sampleName = excel.getCellValue(row.getCell(2)); description = excel.getCellValue(row.getCell(3)); title = excel.getCellValue(row.getCell(4)); comment = excel.getCellValue(row.getCell(5)); logger.info("Sample information for sample number {} is loaded.", sampleNo); } } /** * to support modification option {@inheritDoc} * * @see gda.hrpd.SampleInfo#saveSampleInfo(int) */ @Override public void saveSampleInfo(int sampleNo) { HSSFRow row = sampleInfo.getRow(sampleNo + rowOffset); if (row == null) { // add more row to the spreadsheet row = sampleInfo.createRow(sampleNo + rowOffset); } try { excel.setCellValue(row, 0, carouselNo); excel.setCellValue(row, 1, sampleID); excel.setCellValue(row, 2, sampleName); excel.setCellValue(row, 3, description); excel.setCellValue(row, 4, title); excel.setCellValue(row, 5, comment); excel.write(this.filename); } catch (IOException e) { logger.warn("{}, Cannot save sample information to {}.", e.getMessage(), this.filename); } } @Override public void saveExperimentInfo(int sampleNo) { if (saveExperimentSummary) { HSSFRow row = experimentSummary.getRow(sampleNo + rowOffset); if (row == null) { // add more row to the spreadsheet row = experimentSummary.createRow(sampleNo + rowOffset); } try { excel.setCellValue(row, 0, carouselNo); excel.setCellValue(row, 1, runNumber); excel.setCellValue(row, 2, date); excel.setCellValue(row, 3, time); excel.setCellValue(row, 4, beamline); excel.setCellValue(row, 5, project); excel.setCellValue(row, 6, experiment); excel.setCellValue(row, 7, wavelength); excel.setCellValue(row, 8, temperature); excel.write(this.filename); } catch (IOException e) { logger.warn("{}, Cannot save experiement summary to {}.", e.getMessage(), this.filename); } } else { logger.warn("Cannot save experiment summary to Excel file. {}'s 'saveExperimentSummary' state is {}", getName(), saveExperimentSummary); } } @Override public String getCarouselNo() { return carouselNo; } @Override public void setCarouselNo(String caroselNo) { this.carouselNo = caroselNo; } @Override public void setCarouselNo(int caroselNo) { setCarouselNo(String.valueOf(caroselNo)); } @Override public String getSampleID() { return sampleID; } @Override public void setSampleID(String sampelID) { this.sampleID = sampelID; } @Override public String getSampleName() { return sampleName; } @Override public void setSampleName(String sampelName) { this.sampleName = sampelName; } @Override public String getDescription() { return description; } @Override public void setDescription(String description) { this.description = description; } @Override public String getTitle() { return title; } @Override public void setTitle(String title) { this.title = title; } @Override public String getComment() { return comment; } @Override public void setComment(String comment) { this.comment = comment; } @Override public void setRunNumber(String runNumber) { this.runNumber = runNumber; } @Override public void setDate(String date) { this.date = date; } @Override public void setTime(String time) { this.time = time; } @Override public void setBeamline(String beamline) { this.beamline = beamline; } @Override public void setExperiment(String experiment) { this.experiment = experiment; } @Override public void setProject(String project) { this.project = project; } @Override public void setWavelength(String wavelength) { this.wavelength = wavelength; } @Override public void setTemperature(String temperature) { this.temperature = temperature; } @Override public int getRowOffset() { return rowOffset; } @Override public void setRowOffset(int rowOffset) { this.rowOffset = rowOffset; } @Override public String getSampleInfoFile() { return sampleInfoFile; } @Override public void setSampleInfoFile(String sampleInfoFile) { String oldFile = this.sampleInfoFile; this.sampleInfoFile = sampleInfoFile; if (isConfigured()) { try { reconfigure(sampleInfoFile); } catch (FactoryException e) { this.sampleInfoFile = oldFile; logger.error(e.getMessage(), e); } } } @Override public boolean isSaveExperimentSummary() { return saveExperimentSummary; } @Override public void setSaveExperimentSummary(boolean saveExperimentSummary) { this.saveExperimentSummary = saveExperimentSummary; } /** * @param filename * @throws FactoryException */ private void reconfigure(String filename) throws FactoryException { if (filename.startsWith("/")) { // full path is provided for the constructor. this.filename = filename; } else if (!filename.startsWith("/")) { // assume the file is at user's home directory String processingDir = PathConstructor.createFromDefaultProperty() + File.separator + "processing"; this.filename = processingDir + File.separator + filename; } File file = new File(this.filename); if (!file.exists()) { logger.debug("Cannot find file {}", this.filename); throw new FactoryException("Cannot find file " + this.filename); } setConfigured(false); configure(); } @Override public String getName() { return this.name; } @Override public void setName(String name) { this.name = name; } /** * Checks to see if the created object should be local to the server or whether a corba impl should be instantiated * and placed on the name server. * * @return true for local only objects */ @Override public boolean isLocal() { return local; } /** * Sets a flag to inform the server that the created object should be local to itself or whether a corba impl should * be instantiated and placed on the name server. * * @param local * true if a local only implementation. */ @Override public void setLocal(boolean local) { this.local = local; } /** * Check whether the configure method should be called when the server is instantiated. * * @return true if configuration is required at startup. */ public boolean isConfigureAtStartup() { return configureAtStartup; } /** * Set a flag to inform the server whether the configure method should be called at startup. * * @param configureAtStartup * true to configure at startup. */ public void setConfigureAtStartup(boolean configureAtStartup) { this.configureAtStartup = configureAtStartup; } @Override public void addIObserver(IObserver anIObserver) { observableComponent.addIObserver(anIObserver); } @Override public void deleteIObserver(IObserver anIObserver) { observableComponent.deleteIObserver(anIObserver); } @Override public void deleteIObservers() { observableComponent.deleteIObservers(); } }