/******************************************************************************* * Copyright (c) 2007, 2011 Association for Decentralized Information Management in * Industry THTH ry. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.databoard.binding.impl; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import org.simantics.databoard.Bindings; import org.simantics.databoard.Datatypes; import org.simantics.databoard.binding.Binding; import org.simantics.databoard.binding.RecordBinding; import org.simantics.databoard.binding.error.BindingConstructionException; import org.simantics.databoard.binding.error.BindingException; import org.simantics.databoard.type.OptionalType; import org.simantics.databoard.type.RecordType; /** * This class Binds throwables to the following record: * { detailMessage : Optional(String) } * * The bound throwable class must have constructor( String ). * * @author toni.kalajainen */ public class ThrowableBinding extends RecordBinding { private Class boundClass; private Constructor constructor; private Constructor constructorNoArgs; public ThrowableBinding( Class classToBindTo ) throws BindingConstructionException { this.boundClass = classToBindTo; type = new RecordType(); RecordType rt = (RecordType) type; rt.addComponent("detailMessage", new OptionalType( Datatypes.STRING )); this.componentBindings = new Binding[1]; this.componentBindings[0] = new OptionalBindingDefault( Bindings.STRING ); try { constructor = boundClass.getConstructor( String.class ); constructor.setAccessible( true ); } catch (SecurityException e) { throw new BindingConstructionException( e ); } catch (NoSuchMethodException e) { throw new BindingConstructionException( e ); } try { constructorNoArgs = boundClass.getConstructor(); constructorNoArgs.setAccessible( true ); } catch (SecurityException e) { } catch (NoSuchMethodException e) { } } @Override public Object getComponent(Object obj, int index) throws BindingException { if ( index != 0 ) throw new BindingException("Index out of range"); if ( obj instanceof Throwable == false ) throw new BindingException("not Throwable"); Throwable t = (Throwable) obj; return t.getMessage(); } @Override public Object create(Object... values) throws BindingException { if (values.length!=1) throw new BindingException("Invalid argument"); try { return constructor.newInstance( values ); } catch (IllegalArgumentException e) { throw new BindingException( e ); } catch (InstantiationException e) { throw new BindingException( e ); } catch (IllegalAccessException e) { throw new BindingException( e ); } catch (InvocationTargetException e) { throw new BindingException( e.getCause() ); } } @Override public Object createPartial() throws BindingException { if ( constructorNoArgs!=null ) { try { return constructorNoArgs.newInstance(); } catch (IllegalArgumentException e) { throw new BindingException( e ); } catch (InstantiationException e) { throw new BindingException( e ); } catch (IllegalAccessException e) { throw new BindingException( e ); } catch (InvocationTargetException e) { throw new BindingException( e.getCause() ); } } try { return constructor.newInstance((Object[]) null); } catch (IllegalArgumentException e) { throw new BindingException( e ); } catch (InstantiationException e) { throw new BindingException( e ); } catch (IllegalAccessException e) { throw new BindingException( e ); } catch (InvocationTargetException e) { throw new BindingException( e.getCause() ); } } @Override public void setComponents(Object obj, Object... value) throws BindingException { // if ( value.length != 1 ) throw new BindingException("Array out of range"); // if ( obj instanceof Throwable == false ) throw new BindingException("not Throwable"); // Throwable t = (Throwable) obj; throw new BindingException("Cannot set message to Throwable"); } @Override public void setComponent(Object obj, int index, Object value) throws BindingException { throw new BindingException("Cannot set message to Throwable"); } @Override public boolean isInstance(Object obj) { return obj instanceof Throwable; } @Override protected boolean baseEquals(Object obj) { ThrowableBinding o = (ThrowableBinding)obj; return super.baseEquals(obj) && o.boundClass.equals(boundClass); } @Override public int baseHashCode() { return super.baseHashCode() + 13 * boundClass.hashCode(); } }