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