001    /*
002     * JBoss DNA (http://www.jboss.org/dna)
003     * See the COPYRIGHT.txt file distributed with this work for information
004     * regarding copyright ownership.  Some portions may be licensed
005     * to Red Hat, Inc. under one or more contributor license agreements.
006     * See the AUTHORS.txt file in the distribution for a full listing of 
007     * individual contributors. 
008     *
009     * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
010     * is licensed to you under the terms of the GNU Lesser General Public License as
011     * published by the Free Software Foundation; either version 2.1 of
012     * the License, or (at your option) any later version.
013     *
014     * JBoss DNA is distributed in the hope that it will be useful,
015     * but WITHOUT ANY WARRANTY; without even the implied warranty of
016     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
017     * Lesser General Public License for more details.
018     *
019     * You should have received a copy of the GNU Lesser General Public
020     * License along with this software; if not, write to the Free
021     * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
022     * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
023     */
024    package org.jboss.dna.graph.property;
025    
026    import java.io.IOException;
027    import java.io.InputStream;
028    import java.io.Reader;
029    import java.math.BigDecimal;
030    import java.net.URI;
031    import java.util.Calendar;
032    import java.util.Date;
033    import java.util.Iterator;
034    import java.util.UUID;
035    import org.jboss.dna.common.text.TextDecoder;
036    import org.jboss.dna.common.text.TextEncoder;
037    
038    /**
039     * A factory for {@link Property} values. Each create method may throw one of these exceptions when attempting to convert a
040     * supplied value to the {@link #getPropertyType() factory's type}:
041     * <ul>
042     * <li>{@link IllegalArgumentException} - If the supplied value is invalid in respect to the conversion being attempted.</li>
043     * <li>{@link UnsupportedOperationException} - If a conversion from the supplied value is not supported.</li>
044     * <li>{@link IoException} - If an unexpected problem occurs during the conversion (such as an {@link IOException}).</li>
045     * </ul>
046     * 
047     * @author Randall Hauch
048     * @author John Verhaeg
049     * @param <T> the type of value to create
050     */
051    public interface ValueFactory<T> {
052    
053        static final TextDecoder DEFAULT_DECODER = Path.NO_OP_DECODER;
054        static final TextEncoder DEFAULT_ENCODER = Path.NO_OP_ENCODER;
055    
056        /**
057         * Get the {@link PropertyType type} of values created by this factory.
058         * 
059         * @return the value type; never null
060         */
061        PropertyType getPropertyType();
062    
063        /**
064         * Create a value from a string, using no decoding.
065         * 
066         * @param value the string from which the value is to be created
067         * @return the value, or null if the supplied string is null
068         * @throws ValueFormatException if the conversion from a string could not be performed
069         * @see #create(String, TextDecoder)
070         */
071        T create( String value ) throws ValueFormatException;
072    
073        /**
074         * Create a value from a string, using the supplied decoder.
075         * 
076         * @param value the string from which the value is to be created
077         * @param decoder the decoder that should be used; if null, the {@link #DEFAULT_DECODER default decoder} is used
078         * @return the value, or null if the supplied string is null
079         * @throws ValueFormatException if the conversion from a string could not be performed
080         * @see #create(String)
081         */
082        T create( String value,
083                  TextDecoder decoder ) throws ValueFormatException;
084    
085        /**
086         * Create a value from an integer.
087         * 
088         * @param value the integer from which the value is to be created
089         * @return the value; never null
090         * @throws ValueFormatException if the conversion from an integer could not be performed
091         */
092        T create( int value ) throws ValueFormatException;
093    
094        /**
095         * Create a long from a string.
096         * 
097         * @param value the string from which the long is to be created
098         * @return the value; never null
099         * @throws ValueFormatException if the conversion from a long could not be performed
100         */
101        T create( long value ) throws ValueFormatException;
102    
103        /**
104         * Create a boolean from a string.
105         * 
106         * @param value the boolean from which the value is to be created
107         * @return the value; never null
108         * @throws ValueFormatException if the conversion from a boolean could not be performed
109         */
110        T create( boolean value ) throws ValueFormatException;
111    
112        /**
113         * Create a value from a float.
114         * 
115         * @param value the float from which the value is to be created
116         * @return the value; never null
117         * @throws ValueFormatException if the conversion from a float could not be performed
118         */
119        T create( float value ) throws ValueFormatException;
120    
121        /**
122         * Create a value from a double.
123         * 
124         * @param value the double from which the value is to be created
125         * @return the value; never null
126         * @throws ValueFormatException if the conversion from a double could not be performed
127         */
128        T create( double value ) throws ValueFormatException;
129    
130        /**
131         * Create a value from a decimal.
132         * 
133         * @param value the decimal from which the value is to be created
134         * @return the value, or null if the supplied decimal is null
135         * @throws ValueFormatException if the conversion from a decimal could not be performed
136         */
137        T create( BigDecimal value ) throws ValueFormatException;
138    
139        /**
140         * Create a value from a Calendar instance.
141         * 
142         * @param value the Calendar instance from which the value is to be created
143         * @return the value, or null if the supplied Calendar is null
144         * @throws ValueFormatException if the conversion from a Calendar could not be performed
145         */
146        T create( Calendar value ) throws ValueFormatException;
147    
148        /**
149         * Create a value from a date.
150         * 
151         * @param value the date from which the value is to be created
152         * @return the value, or null if the supplied date is null
153         * @throws ValueFormatException if the conversion from a Date could not be performed
154         */
155        T create( Date value ) throws ValueFormatException;
156    
157        /**
158         * Create a value from a date-time instant.
159         * 
160         * @param value the date-time instant from which the value is to be created
161         * @return the value, or null if the supplied date is null
162         * @throws ValueFormatException if the conversion from a Date could not be performed
163         */
164        T create( DateTime value ) throws ValueFormatException;
165    
166        /**
167         * Create a value from a name.
168         * 
169         * @param value the name from which the value is to be created
170         * @return the value, or null if the supplied name is null
171         * @throws ValueFormatException if the conversion from a name could not be performed
172         */
173        T create( Name value ) throws ValueFormatException;
174    
175        /**
176         * Create a value from a path.
177         * 
178         * @param value the path from which the value is to be created
179         * @return the value, or null if the supplied path is null
180         * @throws ValueFormatException if the conversion from a path could not be performed
181         */
182        T create( Path value ) throws ValueFormatException;
183    
184        /**
185         * Create a value from a reference.
186         * 
187         * @param value the reference from which the value is to be created
188         * @return the value, or null if the supplied reference is null
189         * @throws ValueFormatException if the conversion from a reference could not be performed
190         */
191        T create( Reference value ) throws ValueFormatException;
192    
193        /**
194         * Create a value from a URI.
195         * 
196         * @param value the URI from which the value is to be created
197         * @return the value, or null if the supplied URI is null
198         * @throws ValueFormatException if the conversion from a URI could not be performed
199         */
200        T create( URI value ) throws ValueFormatException;
201    
202        /**
203         * Create a value from a UUID.
204         * 
205         * @param value the UUID from which the value is to be created
206         * @return the value, or null if the supplied URI is null
207         * @throws ValueFormatException if the conversion from a UUID could not be performed
208         */
209        T create( UUID value ) throws ValueFormatException;
210    
211        /**
212         * Create a value from the binary content given by the supplied array.
213         * 
214         * @param value the content to be used to create the value
215         * @return the value, or null if the supplied stream is null
216         * @throws ValueFormatException if the conversion from a byte array could not be performed
217         */
218        T create( byte[] value ) throws ValueFormatException;
219    
220        /**
221         * Create a value from the binary content given by the supplied stream.
222         * 
223         * @param value the binary object to be used to create the value
224         * @return the value, or null if the supplied stream is null
225         * @throws ValueFormatException if the conversion from the binary object could not be performed
226         * @throws IoException If an unexpected problem occurs while accessing the supplied binary value (such as an
227         *         {@link IOException}).
228         */
229        T create( Binary value ) throws ValueFormatException, IoException;
230    
231        /**
232         * Create a value from the binary content given by the supplied stream.
233         * 
234         * @param stream the stream containing the content to be used to create the value
235         * @param approximateLength the approximate length of the content (in bytes)
236         * @return the value, or null if the supplied stream is null
237         * @throws ValueFormatException if the conversion from an input stream could not be performed
238         * @throws IoException If an unexpected problem occurs while accessing the supplied stream (such as an {@link IOException}).
239         */
240        T create( InputStream stream,
241                  long approximateLength ) throws ValueFormatException, IoException;
242    
243        /**
244         * Create a value from a the binary content given by the supplied reader.
245         * 
246         * @param reader the reader containing the content to be used to create the value
247         * @param approximateLength the approximate length of the content (in bytes)
248         * @return the value, or null if the supplied string is null
249         * @throws ValueFormatException if the conversion from a reader could not be performed
250         * @throws IoException If an unexpected problem occurs while accessing the supplied reader (such as an {@link IOException}).
251         */
252        T create( Reader reader,
253                  long approximateLength ) throws ValueFormatException, IoException;
254    
255        /**
256         * Create a value from the specified information by determining which other <code>create</code> method applies and delegating
257         * to that method. Note that this method only will call <code>create</code> methods that take a single parameter; so this
258         * excludes {@link #create(InputStream, long)}, {@link #create(Reader, long)} and {@link #create(String, TextDecoder)}.
259         * 
260         * @param value the value
261         * @return the new value, or null if the supplied parameter is null
262         * @throws ValueFormatException if the conversion from an object could not be performed
263         * @throws IoException If an unexpected problem occurs while accessing the supplied binary value (such as an
264         *         {@link IOException}).
265         */
266        T create( Object value ) throws ValueFormatException, IoException;
267    
268        /**
269         * Create an array of values from an array of string values, using no decoding.
270         * 
271         * @param values the values
272         * @return the values, or null if the supplied string is null
273         * @throws ValueFormatException if the conversion from a string array could not be performed
274         * @see #create(String[], TextDecoder)
275         */
276        T[] create( String[] values ) throws ValueFormatException;
277    
278        /**
279         * Create an array of values from an array of strings, using the supplied decoder.
280         * 
281         * @param values the string values from which the values are to be created
282         * @param decoder the decoder that should be used; if null, the {@link #DEFAULT_DECODER default decoder} is used
283         * @return the value, or null if the supplied string is null
284         * @throws ValueFormatException if the conversion from a string array could not be performed
285         * @see #create(String)
286         */
287        T[] create( String[] values,
288                    TextDecoder decoder ) throws ValueFormatException;
289    
290        /**
291         * Create an array of values from an array of integers.
292         * 
293         * @param values the integers from which the values are to be created
294         * @return the values, or null if the supplied array is null
295         * @throws ValueFormatException if the conversion from an integer array could not be performed
296         */
297        T[] create( int[] values ) throws ValueFormatException;
298    
299        /**
300         * Create an array of values from an array of longs.
301         * 
302         * @param values the longs from which the values are to be created
303         * @return the values, or null if the supplied array is null
304         * @throws ValueFormatException if the conversion from an array of longs could not be performed
305         */
306        T[] create( long[] values ) throws ValueFormatException;
307    
308        /**
309         * Create an array of values from an array of booleans.
310         * 
311         * @param values the booleans from which the values are to be created
312         * @return the values, or null if the supplied array is null
313         * @throws ValueFormatException if the conversion from an array of booleans could not be performed
314         */
315        T[] create( boolean[] values ) throws ValueFormatException;
316    
317        /**
318         * Create an array of values from an array of floats.
319         * 
320         * @param values the floats from which the values are to be created
321         * @return the values, or null if the supplied array is null
322         * @throws ValueFormatException if the conversion from an array of floats could not be performed
323         */
324        T[] create( float[] values ) throws ValueFormatException;
325    
326        /**
327         * Create an array of values from an array of doubles.
328         * 
329         * @param values the doubles from which the values are to be created
330         * @return the values, or null if the supplied array is null
331         * @throws ValueFormatException if the conversion from an array of doubles could not be performed
332         */
333        T[] create( double[] values ) throws ValueFormatException;
334    
335        /**
336         * Create an array of values from an array of decimal values.
337         * 
338         * @param values the decimals from which the values are to be created
339         * @return the values, or null if the supplied array is null
340         * @throws ValueFormatException if the conversion from an array of decimal values could not be performed
341         */
342        T[] create( BigDecimal[] values ) throws ValueFormatException;
343    
344        /**
345         * Create an array of values from an array of Calendar instances.
346         * 
347         * @param values the Calendar instances from which the values are to be created
348         * @return the values, or null if the supplied array is null
349         * @throws ValueFormatException if the conversion from an array of calendar instances could not be performed
350         */
351        T[] create( Calendar[] values ) throws ValueFormatException;
352    
353        /**
354         * Create an array of values from an array of dates.
355         * 
356         * @param values the dates from which the values are to be created
357         * @return the values, or null if the supplied array is null
358         * @throws ValueFormatException if the conversion from an array of date values could not be performed
359         */
360        T[] create( Date[] values ) throws ValueFormatException;
361    
362        /**
363         * Create an array of values from an array of {@link DateTime} instants.
364         * 
365         * @param values the instants from which the values are to be created
366         * @return the values, or null if the supplied array is null
367         * @throws ValueFormatException if the conversion from an array of date values could not be performed
368         */
369        T[] create( DateTime[] values ) throws ValueFormatException;
370    
371        /**
372         * Create an array of values from an array of names.
373         * 
374         * @param values the names from which the values are to be created
375         * @return the values, or null if the supplied array is null
376         * @throws ValueFormatException if the conversion from an array of names could not be performed
377         */
378        T[] create( Name[] values ) throws ValueFormatException;
379    
380        /**
381         * Create an array of values from an array of paths.
382         * 
383         * @param values the paths from which the values are to be created
384         * @return the values, or null if the supplied array is null
385         * @throws ValueFormatException if the conversion from an array of paths could not be performed
386         */
387        T[] create( Path[] values ) throws ValueFormatException;
388    
389        /**
390         * Create an array of values from an array of references.
391         * 
392         * @param values the references from which the values are to be created
393         * @return the values, or null if the supplied array is null
394         * @throws ValueFormatException if the conversion from an array of references could not be performed
395         */
396        T[] create( Reference[] values ) throws ValueFormatException;
397    
398        /**
399         * Create an array of values from an array of URIs.
400         * 
401         * @param values the URIs from which the values are to be created
402         * @return the values, or null if the supplied array is null
403         * @throws ValueFormatException if the conversion from an array of URIs could not be performed
404         */
405        T[] create( URI[] values ) throws ValueFormatException;
406    
407        /**
408         * Create an array of values from an array of UUIDs.
409         * 
410         * @param values the UUIDs from which the values are to be created
411         * @return the values, or null if the supplied array is null
412         * @throws ValueFormatException if the conversion from an array of UUIDs could not be performed
413         */
414        T[] create( UUID[] values ) throws ValueFormatException;
415    
416        /**
417         * Create an array of values from the array of binary content.
418         * 
419         * @param values the array of content to be used to create the values
420         * @return the value, or null if the supplied array is null
421         * @throws ValueFormatException if the conversion from an array of byte arrays could not be performed
422         */
423        T[] create( byte[][] values ) throws ValueFormatException;
424    
425        /**
426         * Create an array of values from the array of binary objects.
427         * 
428         * @param values the values
429         * @return the new value, or null if the supplied parameter is null
430         * @throws ValueFormatException if the conversion from an array of objects could not be performed
431         * @throws IoException If an unexpected problem occurs during the conversion.
432         */
433        T[] create( Binary[] values ) throws ValueFormatException, IoException;
434    
435        /**
436         * Create an array of values from the specified information by determining which other <code>create</code> method applies for
437         * each object and then delegating to that method. Note that this method will not consider {@link #create(InputStream, long)},
438         * {@link #create(Reader, long)} and {@link #create(String, TextDecoder)}.
439         * 
440         * @param values the values
441         * @return the new value, or null if the supplied parameter is null
442         * @throws ValueFormatException if the conversion from an array of objects could not be performed
443         * @throws IoException If an unexpected problem occurs during the conversion.
444         */
445        T[] create( Object[] values ) throws ValueFormatException, IoException;
446    
447        /**
448         * Create an iterator over the values (of an unknown type). The factory converts any values as required. Note that this method
449         * will not consider {@link #create(InputStream, long)}, {@link #create(Reader, long)} and
450         * {@link #create(String, TextDecoder)}.
451         * <p>
452         * This is useful to use when iterating over the {@link Property#getValues() values} of a {@link Property}.
453         * </p>
454         * 
455         * @param values the values
456         * @return the iterator of type <code>T</code> over the values, or null if the supplied parameter is null
457         * @throws ValueFormatException if the conversion from an iterator of objects could not be performed
458         * @throws IoException If an unexpected problem occurs during the conversion.
459         * @see Property#getValues()
460         */
461        Iterator<T> create( Iterator<?> values ) throws ValueFormatException, IoException;
462    
463        /**
464         * Create an iterable with the values (of an unknown type). The factory converts any values as required. Note that this method
465         * will not consider {@link #create(InputStream, long)}, {@link #create(Reader, long)} and
466         * {@link #create(String, TextDecoder)}.
467         * <p>
468         * This is useful to use when converting all the {@link Property#getValues() values} of a {@link Property}.
469         * </p>
470         * Example:
471         * 
472         * <pre>
473         *      Property property = ...
474         *      ExecutionContext executionContext = ...
475         *      ValueFactory&lt;String&gt; stringFactory = executionContext.getValueFactories().getStringFactory();
476         *      for (String token : stringFactory.create(property)) {
477         *          ...
478         *      }
479         * </pre>
480         * 
481         * @param valueIterable the values
482         * @return the iterator of type <code>T</code> over the values, or null if the supplied parameter is null
483         * @throws ValueFormatException if the conversion from an iterator of objects could not be performed
484         * @throws IoException If an unexpected problem occurs during the conversion.
485         * @see Property#getValues()
486         */
487        Iterable<T> create( Iterable<?> valueIterable ) throws ValueFormatException, IoException;
488    }