001/* 002 * HA-JDBC: High-Availability JDBC 003 * Copyright (c) 2004-2007 Paul Ferraro 004 * 005 * This library is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU Lesser General Public License as published by the 007 * Free Software Foundation; either version 2.1 of the License, or (at your 008 * option) any later version. 009 * 010 * This library is distributed in the hope that it will be useful, but WITHOUT 011 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 012 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 013 * for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public License 016 * along with this library; if not, write to the Free Software Foundation, 017 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 018 * 019 * Contact: ferraro@users.sourceforge.net 020 */ 021package net.sf.hajdbc.sync; 022 023import java.beans.Introspector; 024import java.beans.PropertyDescriptor; 025import java.beans.PropertyEditor; 026import java.beans.PropertyEditorManager; 027import java.util.HashMap; 028import java.util.Map; 029import java.util.Properties; 030 031import net.sf.hajdbc.Messages; 032import net.sf.hajdbc.SynchronizationStrategy; 033 034/** 035 * @author Paul Ferraro 036 * @since 1.1 037 */ 038public class SynchronizationStrategyBuilder 039{ 040 private static final String CLASS = "class"; //$NON-NLS-1$ 041 042 private String id; 043 private Class<? extends SynchronizationStrategy> targetClass; 044 private Properties properties; 045 046 /** 047 * Constructs a new SynchronizationStrategyBuilder. 048 */ 049 public SynchronizationStrategyBuilder() 050 { 051 // Do nothing 052 } 053 054 /** 055 * @return the unique identifier for this synchronization strategy 056 */ 057 public String getId() 058 { 059 return this.id; 060 } 061 062 /** 063 * @return a SynchronizationStrategy instance 064 * @throws Exception 065 */ 066 public SynchronizationStrategy buildStrategy() throws Exception 067 { 068 SynchronizationStrategy strategy = this.targetClass.asSubclass(SynchronizationStrategy.class).newInstance(); 069 070 PropertyDescriptor[] descriptors = Introspector.getBeanInfo(this.targetClass).getPropertyDescriptors(); 071 072 Map<String, PropertyDescriptor> propertyDescriptorMap = new HashMap<String, PropertyDescriptor>(); 073 074 for (PropertyDescriptor descriptor: descriptors) 075 { 076 // Prevent Object.getClass() from being read as a property 077 if (descriptor.getName().equals(CLASS)) continue; 078 079 propertyDescriptorMap.put(descriptor.getName(), descriptor); 080 } 081 082 for (Object key: this.properties.keySet()) 083 { 084 String name = (String) key; 085 086 PropertyDescriptor descriptor = propertyDescriptorMap.get(name); 087 088 if (descriptor == null) 089 { 090 throw new IllegalArgumentException(Messages.getMessage(Messages.INVALID_PROPERTY, name, this.getClass().getName())); 091 } 092 093 PropertyEditor editor = PropertyEditorManager.findEditor(descriptor.getPropertyType()); 094 095 String textValue = this.properties.getProperty(name); 096 097 try 098 { 099 if (editor == null) 100 { 101 throw new Exception(); 102 } 103 104 editor.setAsText(textValue); 105 } 106 catch (Exception e) 107 { 108 throw new IllegalArgumentException(Messages.getMessage(Messages.INVALID_PROPERTY_VALUE, textValue, name, this.targetClass.getName())); 109 } 110 111 descriptor.getWriteMethod().invoke(strategy, editor.getValue()); 112 } 113 114 return strategy; 115 } 116 117 /** 118 * @param id 119 * @param strategy 120 * @return a builder for this strategy 121 * @throws Exception 122 */ 123 public static SynchronizationStrategyBuilder getBuilder(String id, SynchronizationStrategy strategy) throws Exception 124 { 125 SynchronizationStrategyBuilder builder = new SynchronizationStrategyBuilder(); 126 127 builder.id = id; 128 129 Class<? extends SynchronizationStrategy> strategyClass = strategy.getClass(); 130 131 builder.targetClass = strategyClass; 132 133 builder.properties = new Properties(); 134 135 PropertyDescriptor[] descriptors = Introspector.getBeanInfo(strategyClass).getPropertyDescriptors(); 136 137 for (PropertyDescriptor descriptor: descriptors) 138 { 139 // Prevent Object.getClass() from being written as a property 140 if (descriptor.getName().equals(CLASS)) continue; 141 142 PropertyEditor editor = PropertyEditorManager.findEditor(descriptor.getPropertyType()); 143 144 if (editor == null) continue; 145 146 editor.setValue(descriptor.getReadMethod().invoke(strategy)); 147 148 builder.properties.setProperty(descriptor.getName(), editor.getAsText()); 149 } 150 151 return builder; 152 } 153}