package com.framsticks.params; import static com.framsticks.util.lang.Containers.filterInstanceof; import org.apache.log4j.Logger; import com.framsticks.util.UnimplementedException; /** * The Class SimpleAbstractAccess implements all the methods of AccessInterface * which actions can be implemented with usage of {@link AccessInterface} methods * or concern schema, which is stored in {@link #framsClass} * * Based on c++ class SimpleAbstractParam located in: cpp/gdk/param.* * * @author Jarek Szymczak , Mateusz Jarus (please * replace name and surname with my personal data) * * @author Piotr Sniegowski */ public abstract class SimpleAbstractAccess implements AccessInterface { private final static Logger log = Logger.getLogger(SimpleAbstractAccess.class.getName()); protected final FramsClass framsClass; /** * @param framsClass */ public SimpleAbstractAccess(FramsClass framsClass) { this.framsClass = framsClass; } @Override public final FramsClass getFramsClass() { return framsClass; } /** * Simple String key, value class. */ public static class Entry { public final String key; public final String value; public Entry(String key, String value) { this.key = key; this.value = value; } @Override public String toString() { return key + " = " + value; } } @Override public String getId() { return framsClass.getId(); } @Override public int getParamCount() { return framsClass.getParamCount(); } @Override public Param getParam(int i) { return framsClass.getParam(i); } @Override public Param getParam(String id) { return framsClass.getParam(id); } // @Override // public Param getGroupMember(int gi, int n) { // return framsClass.getGroupMember(gi, n); // } @Override public T get(int i, Class type) { return get(framsClass.getParamEntry(i, ValueParam.class), type); } @Override public T get(String id, Class type) { return get(framsClass.getParamEntry(id, ValueParam.class), type); } @Override public int set(int i, T value) { return set(framsClass.getParamEntry(i, ValueParam.class), value); } @Override public int set(String id, T value) { return set(framsClass.getParamEntry(id, ValueParam.class), value); } @Override public int set(ValueParam param, T value) { int flags = 0; //String id = param.getEffectiveId(); try { Object oldValue = get(param, param.getStorageType()); ReassignResult result = param.reassign(value, oldValue); Object casted = result.getValue(); if (casted != null && !casted.equals(oldValue)) { internalSet(param, casted); } flags = result.getFlags(); } catch (CastFailure e) { log.error("casting failure while set: ", e); } return flags; } @Override public void setDefault(boolean numericOnly) { for (int i = 0; i < framsClass.getParamCount(); i++) { setDefault(i, numericOnly); } } @Override public void setDefault(int i, boolean numericOnly) { ValueParam entry = framsClass.getParamEntry(i, ValueParam.class); if ((entry != null) && (!numericOnly || entry.isNumeric())) { set(i, entry.getDef(entry.getStorageType())); } } @Override public void setMin() { for (int i = 0; i < framsClass.getParamCount(); i++) { setMin(i); } } @Override public void setMin(int i) { PrimitiveParam entry = framsClass.getParamEntry(i, PrimitiveParam.class); Object min = entry.getMin(entry.getStorageType()); if (min != null) { set(i, min); } } @Override public void setMax() { for (int i = 0; i < framsClass.getParamCount(); i++) { setMax(i); } } @Override public void setMax(int i) { PrimitiveParam entry = framsClass.getParamEntry(i, PrimitiveParam.class); Object max = entry.getMax(entry.getStorageType()); if (max != null) { set(i, max); } } @Override public void copyFrom(AccessInterface src) { throw new UnimplementedException(); // clearValues(); //TODO: iterate over self, and pull from src /* for (int i = 0; i < src.getFramsClass().size(); i++) { this.set(i, src.get(i, Object.class)); } */ } @Override public void save(SinkInterface sink) { assert framsClass != null; sink.print(framsClass.getId()).print(":").breakLine(); for (PrimitiveParam p : filterInstanceof(framsClass.getParamEntries(), PrimitiveParam.class)) { Object value = get(p, Object.class); if ((value == null) || value.equals(p.getDef(Object.class))) { continue; } sink.print(p.getId()).print(":"); p.save(sink, value); sink.breakLine(); } sink.breakLine(); } private Entry readEntry(SourceInterface source) { String line; String key = null; StringBuilder value = null; while ((line = source.readLine()) != null) { if (key == null) { int colonIndex = line.indexOf(':'); if (colonIndex == -1) { return null; } key = line.substring(0, colonIndex); String inlineValue = line.substring(colonIndex + 1); if (!inlineValue.startsWith("~")) { return new Entry(key, inlineValue); } value = new StringBuilder(); value.append(inlineValue.substring(1)); continue; } if (value.length() != 0) { value.append(System.getProperty("line.separator")); } if (line.contains("~")) { value.append(line.substring(0, line.indexOf("~"))); return new Entry(key, value.toString()); } value.append(line); /* if (line.contains("~")) { String lastLine = line.substring(0, line.indexOf("~")); if (lastLine.length() > 0) { appendToValue(value, lastLine); } return new Entry(key, value.toString()); } appendToValue(value, line); */ } return null; } @Override public void load(SourceInterface source) { //TODO not clearing values, because get from manager gives only fields, not children //this.clearValues(); Entry entry; while ((entry = readEntry(source)) != null) { Param param = getParam(entry.key); if (param == null) { continue; } if (!(param instanceof ValueParam)) { log.warn("param " + param + " is not a ValueParam"); continue; } if ((param.getFlags() & Flags.DONTLOAD) != 0) { log.debug("DontLoad flag was set - not loading..."); } else { int retFlags = this.set((ValueParam) param, entry.value); if ((retFlags & (Flags.PSET_HITMIN | Flags.PSET_HITMAX)) != 0) { String which = ((retFlags & Flags.PSET_HITMIN) != 0) ? "small" : "big"; log.warn("value of key '" + entry.key + "' was too " + which + ", adjusted"); } } } } protected abstract void internalSet(ValueParam param, T value); @Override public Iterable getParams() { return framsClass.getParamEntries(); } @Override public int getCompositeParamCount() { return framsClass.getCompositeParamCount(); } @Override public CompositeParam getCompositeParam(int number) { return framsClass.getCompositeParam(number); } /* protected > int setAndCut(Param param, Object value, Class type) { int flags = 0; T val = type.cast(value); T min = param.getMin(type); T max = param.getMax(type); if (min != null && val.compareTo(min) < 0) { val = min; flags |= Flags.PSET_HITMIN; } if (max != null && val.compareTo(max) > 0) { val = max; flags |= Flags.PSET_HITMAX; } internalSet(param, val); return flags; }*/ }