1 /* 2 * Copyright 2012-2013 smartics, Kronseder & Reiner GmbH 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package de.smartics.properties.spi.config.ds; 17 18 import java.sql.Connection; 19 import java.sql.ResultSet; 20 import java.sql.SQLException; 21 import java.util.Iterator; 22 import java.util.NoSuchElementException; 23 24 import javax.annotation.concurrent.NotThreadSafe; 25 26 import de.smartics.properties.api.config.domain.Property; 27 import de.smartics.properties.api.config.domain.PropertyCollection; 28 import de.smartics.properties.api.config.domain.PropertyLocation; 29 30 /** 31 * Implementation of {@link PropertyCollection} based on accessing a data 32 * source. 33 */ 34 @NotThreadSafe 35 public final class DsPropertyCollection implements PropertyCollection 36 { 37 // ********************************* Fields ********************************* 38 39 // --- constants ------------------------------------------------------------ 40 41 // --- members -------------------------------------------------------------- 42 43 /** 44 * The identifier of the data source the properties are read from. 45 */ 46 private final String dataSourceId; 47 48 /** 49 * The underlying connection of the result set. 50 */ 51 private final Connection connection; 52 53 /** 54 * The properties to iterate over. 55 */ 56 private final ResultSet resultSet; 57 58 // ****************************** Initializer ******************************* 59 60 // ****************************** Constructors ****************************** 61 62 /** 63 * Default constructor. 64 * 65 * @param dataSourceId the identifier of the data source the properties are 66 * read from. 67 * @param connection the underlying connection of the result set. 68 * @param resultSet the properties to iterate over. 69 */ 70 public DsPropertyCollection(final String dataSourceId, 71 final Connection connection, final ResultSet resultSet) 72 { 73 this.dataSourceId = dataSourceId; 74 this.connection = connection; 75 this.resultSet = resultSet; 76 } 77 78 // ****************************** Inner Classes ***************************** 79 80 /** 81 * Maps the result set iteration to a Java iterator. 82 */ 83 private final class ResultSetIterator implements Iterator<Property> 84 { 85 // ******************************** Fields ******************************** 86 87 // --- constants ---------------------------------------------------------- 88 89 // --- members ------------------------------------------------------------ 90 /** 91 * A reference to the next property to return. 92 */ 93 private Property nextProperty; 94 95 // ***************************** Initializer ****************************** 96 97 // ***************************** Constructors ***************************** 98 99 // ***************************** Inner Classes **************************** 100 101 // ******************************** Methods ******************************* 102 103 // --- init --------------------------------------------------------------- 104 105 // --- get&set ------------------------------------------------------------ 106 107 // --- business ----------------------------------------------------------- 108 109 @Override 110 public boolean hasNext() 111 { 112 provideProperty(); 113 return nextProperty != null; 114 } 115 116 @Override 117 public Property next() 118 { 119 provideProperty(); 120 121 if (nextProperty == null) 122 { 123 throw new NoSuchElementException( 124 "No further elements in collection from data source '" 125 + dataSourceId + "'."); 126 } 127 128 final Property currentProperty = nextProperty; 129 nextProperty = null; 130 return currentProperty; 131 } 132 133 /** 134 * {@inheritDoc} 135 * <p> 136 * Not supported by this implementation. 137 * </p> 138 * 139 * @throws UnsupportedOperationException always. 140 */ 141 @Override 142 public void remove() throws UnsupportedOperationException 143 { 144 throw new UnsupportedOperationException("Remove not supported."); 145 } 146 147 private void provideProperty() 148 { 149 if (nextProperty == null) 150 { 151 try 152 { 153 if (resultSet.next()) 154 { 155 final String name = resultSet.getString(1); 156 final String value = resultSet.getString(2); 157 nextProperty = 158 new Property(new PropertyLocation(dataSourceId), name, value); 159 } 160 else 161 { 162 close(); 163 } 164 } 165 catch (final SQLException e) 166 { 167 close(); 168 throw new IllegalStateException( 169 "Cannot read next property from data source '" + dataSourceId 170 + "'."); 171 172 } 173 } 174 } 175 176 // --- object basics ------------------------------------------------------ 177 } 178 179 // ********************************* Methods ******************************** 180 181 // --- init ----------------------------------------------------------------- 182 183 // --- get&set -------------------------------------------------------------- 184 185 // --- business ------------------------------------------------------------- 186 187 /** 188 * {@inheritDoc} 189 * 190 * @see java.lang.Iterable#iterator() 191 */ 192 @Override 193 public Iterator<Property> iterator() 194 { 195 return new ResultSetIterator(); 196 } 197 198 /** 199 * Closes the collection to release the underlying connection. 200 * <p> 201 * The connection is automatically closed when the iterator reaches the last 202 * element. 203 * </p> 204 */ 205 @Override 206 public void close() 207 { 208 try 209 { 210 if (!connection.isClosed()) 211 { 212 connection.close(); 213 } 214 } 215 catch (final SQLException e) 216 { 217 // Ignore 218 } 219 } 220 221 // --- object basics -------------------------------------------------------- 222 223 }