/* Copyright (C) 2006 Christian Schneider * * This file is part of Nomad. * * Nomad 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. * * Nomad 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 Nomad; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package net.sf.nmedit.jtheme.store2; import java.io.IOException; import java.io.Serializable; import java.lang.reflect.Method; import java.util.Iterator; import java.util.List; import net.sf.nmedit.jpatch.PModule; import net.sf.nmedit.jpatch.PParameter; import net.sf.nmedit.jtheme.component.JTComponent; import net.sf.nmedit.jtheme.component.JTParameterControlAdapter; import net.sf.nmedit.jtheme.store.StorageContext; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jdom.Attribute; import org.jdom.Element; public abstract class AbstractMultiParameterElement extends AbstractElement implements Serializable { protected transient String[] parameterElementNames; protected transient String[] componentIdList; protected transient Object[] valueList; // (String,Integer) pairs protected BindParameterInfo bindings = null; public AbstractMultiParameterElement(String[] parameterElementNames) { this.parameterElementNames = parameterElementNames; componentIdList = new String[parameterElementNames.length]; } public AbstractMultiParameterElement(Class<? extends JTComponent> jtclass) { BindParameterInfo info = BindParameterInfo.forClass(jtclass); this.bindings = info; parameterElementNames = new String[info.getAdapterCount()]; componentIdList = new String[info.getAdapterCount()]; Iterator<String> iter = info.parameters(); int i=0; while (iter.hasNext()) parameterElementNames[i++] = iter.next(); int cnt = info.getAdapterCount(); if (cnt>0) valueList = new Object[cnt*2]; iter = info.values(); i=0; while (iter.hasNext()) { String name = iter.next(); valueList[i++] = name; valueList[i++] = null; } } @Override protected void initElement(StorageContext context, Element e) { super.initElement(context, e); initComponentIdList(e); } protected void initComponentIdList(Element e) { List<?> children = e.getChildren(); for (int i=children.size()-1;i>=0;i--) { Element p = (Element) children.get(i); for (int index=parameterElementNames.length-1;index>=0;index--) { String n = parameterElementNames[index]; if (n.equals(p.getName())) { Attribute a = p.getAttribute(ATT_COMPONENT_ID); if (a != null) { componentIdList[index] = a.getValue(); } break; } } // default values for component Attribute a = p.getAttribute(ATT_VALUE); if (a != null) { int intValue; try { intValue = Integer.parseInt(a.getValue()); } catch (NumberFormatException nfe) { continue; } if (valueList != null) { for (int index=0;index<valueList.length;index+=2) { String name = (String) valueList[index]; if (name.equals(p.getName())) { valueList[index+1] = intValue; break; } } } } } } protected void link(JTComponent component, PModule module) { if (bindings == null) throw new UnsupportedOperationException(); for (int i=0;i<parameterElementNames.length;i++) { String name = parameterElementNames[i]; PParameter param = module.getParameterByComponentId(componentIdList[i]); if (param != null) { // set adapter Method setter = bindings.getAdapterSetter(name); int index = bindings.getAdapterSetterIndex(name); try { JTParameterControlAdapter adapter = new JTParameterControlAdapter(param); if (index < 0) { // one arg Object[] args = new Object[]{adapter} ; setter.invoke(component, args); PParameter extParam = param.getExtensionParameter(); if (extParam != null) { JTParameterControlAdapter extParamAdapt = new JTParameterControlAdapter(extParam); Method setterExt = bindings.getAdapterSetter(name+"Extension"); Object[] argsExt = new Object[]{extParamAdapt} ; if (setterExt != null) setterExt.invoke(component, argsExt); else { // TODO: detect which component don't handle morph // for example: curves //System.out.println(extParam.getName()+" "+component); } } } else { // several args Object[] args = new Object[]{index, adapter}; setter.invoke(component, args); PParameter extParam = param.getExtensionParameter(); if (extParam != null) { JTParameterControlAdapter extParamAdapt = new JTParameterControlAdapter(extParam); String extName; if( index > 9) { extName = name.substring(0,name.length()-2)+"Extension"+index; } else{ extName = name.substring(0,name.length()-1)+"Extension"+index; } Method setterExt = bindings.getAdapterSetter(extName); Object[] argsExt = new Object[]{index,extParamAdapt} ; if (setterExt != null) { setterExt.invoke(component, argsExt); } else { // TODO: detect which component don't handle morph // for example: curves //System.out.println(extParam.getName()+" "+component); } } } } catch (Throwable t) { Log log = LogFactory.getLog(getClass()); if (log.isTraceEnabled()) { log.trace("error in link("+component+","+module+")", t); } } } else { // log: parameter not found } } if (valueList != null) { for (int i=0;i<valueList.length;i+=2) { String name = (String) valueList[i]; Integer value = (Integer) valueList[i+1]; if (value != null) { Method setter = bindings.getValueSetter(name); try { setter.invoke(component, new Object[]{value}); } catch (Exception e) { Log log = LogFactory.getLog(getClass()); if (log.isTraceEnabled()) { log.trace("error in link("+component+","+module+")", e); } } } } } } private void writeObject(java.io.ObjectOutputStream out) throws IOException { out.defaultWriteObject(); out.writeInt(parameterElementNames.length); int size = 0; for (int i=0;i<parameterElementNames.length;i++) { String n = parameterElementNames[i]; if (n!=null) size++; } out.writeInt(size); for (int i=0;i<parameterElementNames.length;i++) { String n = parameterElementNames[i]; if (n != null) { out.writeInt(i); out.writeObject(n); } } size = 0; for (int i=0;i<componentIdList.length;i++) { String n = componentIdList[i]; if (n!=null) size++; } out.writeInt(size); for (int i=0;i<componentIdList.length;i++) { String n = componentIdList[i]; if (n != null) { out.writeInt(i); out.writeObject(n); } } size = 0; if (valueList != null) { for (int i=1;i<valueList.length;i+=2) { if (valueList[i] != null) size++; } } out.writeInt(size); if (valueList!=null) { for (int i=0;i<valueList.length;i+=2) { String n = (String) valueList[i]; Integer v = (Integer) valueList[i+1]; if (v != null) { out.writeObject(n); out.writeInt(v.intValue()); } } } } private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); int size = in.readInt(); parameterElementNames = new String[size]; componentIdList = new String[size]; size = in.readInt(); for (int i=0;i<size;i++) { int index = in.readInt(); String n = (String) in.readObject(); parameterElementNames[index] = n; } size = in.readInt(); for (int i=0;i<size;i++) { int index = in.readInt(); String n = (String) in.readObject(); componentIdList[index] = n; } size = in.readInt(); if (size>0) { valueList = new Object[size*2]; for (int i=0;i<size;i+=2) { String name = (String) in.readObject(); int value = in.readInt(); valueList[i] = name; valueList[i+1] = value; } } } }