/* * Copyright 2002-2006 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package org.springframework.richclient.settings.jdbc; import java.io.IOException; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import javax.sql.DataSource; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.richclient.settings.AbstractSettings; import org.springframework.richclient.settings.Settings; /** * * @author Peter De Bruycker */ public class JdbcSettings extends AbstractSettings { private DataSource dataSource; private Integer id; private String user; private Map values = new HashMap(); private Set remove = new HashSet(); private Set add = new HashSet(); private Set update = new HashSet(); private String[] childKeys; public JdbcSettings( DataSource ds, String user, Integer id, String key ) { this( null, ds, user, id, key ); } public JdbcSettings( JdbcSettings parent, DataSource ds, String user, Integer id, String key ) { super( parent, key ); this.id = id; // TODO assert dataSource not null dataSource = ds; // TODO assert user not empty this.user = user; } protected boolean internalContains( String key ) { return values.containsKey( key ); } protected String[] internalGetChildSettings() { if( childKeys == null ) { loadChildKeys(); } return childKeys; } protected Settings internalCreateChild( String key ) { return new JdbcSettings( this, dataSource, user, null, key ); } protected void internalSet( String key, String value ) { boolean isNew = !values.containsKey( key ) || add.contains( key ); values.put( key, value ); if( isNew ) { add.add( key ); } else { update.add( key ); } remove.remove( key ); } protected String internalGet( String key ) { return (String) values.get( key ); } protected void internalRemove( String key ) { values.remove( key ); if( !add.contains( key ) ) { remove.add( key ); } update.remove( key ); add.remove( key ); } public String[] getKeys() { return (String[]) values.keySet().toArray( new String[0] ); } public Integer getId() { return id; } public void save() throws IOException { if( getParent() != null ) { getParent().save(); } JdbcTemplate template = new JdbcTemplate( dataSource ); // if this is a new node, insert it if( id == null ) { JdbcSettings parent = (JdbcSettings) getParent(); template.update( "INSERT INTO SETTINGS (KEY, PARENT, USER) VALUES (?, ?, ?)", new Object[] { getName(), parent == null ? null : parent.getId(), user } ); id = Integer.valueOf( template.queryForInt( "SELECT MAX(ID) FROM SETTINGS" ) ); } else { for( Iterator iter = remove.iterator(); iter.hasNext(); ) { String key = (String) iter.next(); template.update( "REMOVE FROM SETTINGS_VALUES WHERE SETTINGS_ID=? AND KEY=?", new Object[] { id, key } ); } for( Iterator iter = update.iterator(); iter.hasNext(); ) { String key = (String) iter.next(); template.update( "UPDATE SETTINGS_VALUES SET VALUE=? WHERE SETTINGS_ID=? AND KEY=?", new Object[] { values.get( key ), id, key } ); } } for( Iterator iter = add.iterator(); iter.hasNext(); ) { String key = (String) iter.next(); template.update( "INSERT INTO SETTINGS_VALUES (SETTINGS_ID, KEY, VALUE) VALUES (?, ?, ?)", new Object[] { id, key, values.get( key ) } ); } remove.clear(); update.clear(); add.clear(); } public void load() throws IOException { if( id == null ) { return; } JdbcTemplate template = new JdbcTemplate( dataSource ); List entries = template.queryForList( "SELECT KEY, VALUE FROM SETTINGS_VALUES WHERE SETTINGS_ID=?", new Object[] { id } ); for( Iterator iter = entries.iterator(); iter.hasNext(); ) { Map entry = (Map) iter.next(); values.put(entry.get( "KEY" ), entry.get( "VALUE" )); } } private void loadChildKeys() { JdbcTemplate template = new JdbcTemplate( dataSource ); List keys = template.queryForList( "SELECT KEY FROM SETTINGS WHERE PARENT=" + id, String.class ); childKeys = (String[]) keys.toArray( new String[keys.size()] ); } public String getUser() { return user; } public void internalRemoveSettings() { if( id != null ) { // first delete all children for( int i = 0; i < childKeys.length; i++ ) { getSettings(childKeys[i]).removeSettings(); } // now delete all values JdbcTemplate template = new JdbcTemplate( dataSource ); template.update( "DELETE FROM SETTINGS_VALUES WHERE SETTINGS_ID=?", new Object[] { id } ); // now delete our own record template.update( "DELETE FROM SETTINGS WHERE ID=?", new Object[] { id } ); id = null; } values.clear(); remove.clear(); add.clear(); update.clear(); } }