/* * AbstractOptionHandler.java * Copyright (C) 2007 University of Waikato, Hamilton, New Zealand * @author Richard Kirkby (rkirkby@cs.waikato.ac.nz) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ package tr.gov.ulakbim.jDenetX.options; import tr.gov.ulakbim.jDenetX.AbstractMOAObject; import tr.gov.ulakbim.jDenetX.classifiers.splits.InfoGainSplitCriterion; import tr.gov.ulakbim.jDenetX.core.ObjectRepository; import tr.gov.ulakbim.jDenetX.tasks.NullMonitor; import tr.gov.ulakbim.jDenetX.tasks.TaskMonitor; import java.lang.reflect.Field; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; public abstract class AbstractOptionHandler extends AbstractMOAObject implements OptionHandler { private static final long serialVersionUID = 1L; protected Options options; protected Map<String, Object> classOptionNamesToPreparedObjects; public String getPurposeString() { return "Anonymous object: purpose undocumented."; } public Options getOptions() { if (this.options == null) { this.options = new Options(); Option[] myOptions = discoverOptionsViaReflection(); for (Option option : myOptions) { this.options.addOption(option); } } return this.options; } public void prepareForUse() { prepareForUse(new NullMonitor(), null); } public void prepareForUse(TaskMonitor monitor, ObjectRepository repository) { prepareClassOptions(monitor, repository); prepareForUseImpl(monitor, repository); } protected abstract void prepareForUseImpl(TaskMonitor monitor, ObjectRepository repository); public String getCLICreationString(Class<?> expectedType) { return ClassOption.stripPackagePrefix(this.getClass().getName(), expectedType) + " " + getOptions().getAsCLIString(); } @Override public OptionHandler copy() { return (OptionHandler) super.copy(); } protected Option[] discoverOptionsViaReflection() { Class<? extends AbstractOptionHandler> c = this.getClass(); Field[] fields = c.getFields(); List<Option> optList = new LinkedList<Option>(); for (Field field : fields) { String fName = field.getName(); Class<?> fType = field.getType(); if (fName.endsWith("Option")) { if (Option.class.isAssignableFrom(fType)) { Option oVal = null; try { field.setAccessible(true); oVal = (Option) field.get(this); } catch (IllegalAccessException ignored) { // cannot access this field } if (oVal != null) { optList.add(oVal); } } } } return optList.toArray(new Option[optList.size()]); } protected void prepareClassOptions(TaskMonitor monitor, ObjectRepository repository) { this.classOptionNamesToPreparedObjects = null; Option[] optionArray = getOptions().getOptionArray(); for (Option option : optionArray) { if (option instanceof ClassOption) { ClassOption classOption = (ClassOption) option; monitor.setCurrentActivity("Materializing option " + classOption.getName() + "...", -1.0); Object optionObj = classOption.materializeObject(monitor, repository); if (monitor.taskShouldAbort()) { return; } if (optionObj instanceof OptionHandler) { monitor.setCurrentActivity("Preparing option " + classOption.getName() + "...", -1.0); ((OptionHandler) optionObj).prepareForUse(monitor, repository); if (monitor.taskShouldAbort()) { return; } } if (this.classOptionNamesToPreparedObjects == null) { this.classOptionNamesToPreparedObjects = new HashMap<String, Object>(); } this.classOptionNamesToPreparedObjects.put(option.getName(), optionObj); } } } //TODO fix this hack protected Object getPreparedClassOption(ClassOption opt) { //System.out.println("Class Option Name:" + this.classOptionNamesToPreparedObjects.get(opt.getName())); Object object = null; try { object = this.classOptionNamesToPreparedObjects.get(opt.getName()); } catch (NullPointerException npex) { //There is a problem with splitClassOption to fix that issue temproraly added this code: object = new InfoGainSplitCriterion(); } return object; } }